package com.dragon.mmochat.service;

import java.awt.Color;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.EmptyResultDataAccessException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.dragon.mmochat.MmochatConstant;
import com.dragon.mmochat.MmochatMain;
import com.dragon.mmochat.message.Mmochat_11_3C;
import com.dragon.mmochat.message.Mmochat_11_4C;
import com.dragon.mmochat.message.Mmochat_11_6C;
import com.dragon.mmochat.message.Mmochat_20_10C;
import com.dragon.mmochat.message.Mmochat_20_11C;
import com.dragon.mmochat.message.Mmochat_20_12C;
import com.dragon.mmochat.message.Mmochat_20_13C;
import com.dragon.mmochat.message.Mmochat_20_14C;
import com.dragon.mmochat.message.Mmochat_20_15C;
import com.dragon.mmochat.message.Mmochat_20_16C;
import com.dragon.mmochat.message.Mmochat_20_17C;
import com.dragon.mmochat.message.Mmochat_20_18C;
import com.dragon.mmochat.message.Mmochat_20_19C;
import com.dragon.mmochat.message.Mmochat_20_1C;
import com.dragon.mmochat.message.Mmochat_20_20C;
import com.dragon.mmochat.message.Mmochat_20_21C;
import com.dragon.mmochat.message.Mmochat_20_22C;
import com.dragon.mmochat.message.Mmochat_20_23C;
import com.dragon.mmochat.message.Mmochat_20_25C;
import com.dragon.mmochat.message.Mmochat_20_2C;
import com.dragon.mmochat.message.Mmochat_20_3C;
import com.dragon.mmochat.message.Mmochat_20_5C;
import com.dragon.mmochat.message.Mmochat_20_6C;
import com.dragon.mmochat.message.Mmochat_20_7C;
import com.dragon.mmochat.message.Mmochat_20_8C;
import com.dragon.mmochat.message.Mmochat_20_9C;
import com.dragon.mmochat.message.Mmochat_ClientVersionError;
import com.dragon.mmochat.message.Mmochat_ServerStateMessage;
import com.dragon.mmochat.model.MmochatDelayPay;
import com.dragon.mmochat.model.MmochatHistoryChat;
import com.dragon.mmochat.model.MmochatStandardKefuProblem;
import com.dragon.mmochat.model.deal.MmochatDealLog;
import com.dragon.mmochat.model.enumType.MmochatBigMoneyCostType;
import com.dragon.mmochat.model.enumType.MmochatBigMoneyEarnType;
import com.dragon.mmochat.model.enumType.MmochatChenHaoType;
import com.dragon.mmochat.model.enumType.MmochatDelayPayState;
import com.dragon.mmochat.model.enumType.MmochatDrugType;
import com.dragon.mmochat.model.enumType.MmochatEquipQualityType;
import com.dragon.mmochat.model.enumType.MmochatEquipType;
import com.dragon.mmochat.model.enumType.MmochatMaterialType;
import com.dragon.mmochat.model.enumType.MmochatOtherSystemSettingType;
import com.dragon.mmochat.model.enumType.MmochatPetType;
import com.dragon.mmochat.model.enumType.MmochatPhoneCardType;
import com.dragon.mmochat.model.enumType.MmochatPropType;
import com.dragon.mmochat.model.enumType.MmochatRoleDealState;
import com.dragon.mmochat.model.enumType.MmochatRoleType;
import com.dragon.mmochat.model.enumType.MmochatServerStateType;
import com.dragon.mmochat.model.enumType.MmochatSkillType;
import com.dragon.mmochat.model.enumType.MmochatSmallMoneyCostType;
import com.dragon.mmochat.model.enumType.MmochatSmallMoneyEarnType;
import com.dragon.mmochat.model.enumType.MmochatStoneBetState;
import com.dragon.mmochat.model.enumType.MmochatStorePwdState;
import com.dragon.mmochat.model.enumType.MmochatSuperMachineType;
import com.dragon.mmochat.model.gang.MmochatGang;
import com.dragon.mmochat.model.gang.MmochatGangMember;
import com.dragon.mmochat.model.kefu.MmochatKefuQuestion;
import com.dragon.mmochat.model.map.MmochatMapGuiderData;
import com.dragon.mmochat.model.object.MmochatCommonObject;
import com.dragon.mmochat.model.object.MmochatDrug;
import com.dragon.mmochat.model.object.MmochatMaterial;
import com.dragon.mmochat.model.object.MmochatPackageGrid;
import com.dragon.mmochat.model.object.MmochatProp;
import com.dragon.mmochat.model.object.MmochatPropEffect;
import com.dragon.mmochat.model.object.MmochatSuperMachine;
import com.dragon.mmochat.model.playerBet.MmochatStoneBet;
import com.dragon.mmochat.model.role.MmochatGm;
import com.dragon.mmochat.model.role.MmochatMonster;
import com.dragon.mmochat.model.role.MmochatPet;
import com.dragon.mmochat.model.role.MmochatPlayer;
import com.dragon.mmochat.model.role.MmochatTempNpc;
import com.dragon.mmochat.model.roleDeal.MmochatPhoneCard;
import com.dragon.mmochat.model.roleDeal.MmochatRoleDeal;
import com.dragon.mmochat.model.scheduleJob.pkGame.activities.MmochatGangMixedPkGame;
import com.dragon.mmochat.model.skill.MmochatSkill;
import com.dragon.mmochat.model.statistics.MmochatBigMoneyStatistics;
import com.dragon.mmochat.model.statistics.MmochatDailyMoneyStatistics;
import com.dragon.mmochat.model.statistics.MmochatDailyUserStatistics;
import com.dragon.mmochat.model.statistics.MmochatMonthlyStatistics;
import com.dragon.mmochat.model.statistics.MmochatOnlineInfo;
import com.dragon.mmochat.model.statistics.MmochatRoleLevelInfo;
import com.dragon.mmochat.model.statistics.MmochatSmallMoneyStatistics;
import com.dragon.mmochat.model.task.MmochatTask;
import com.dragon.mmochat.model.task.MmochatTempTask;
import com.dragon.mmochat.util.CreateTlvWin;
import com.dragon.mmochat.util.MmochatUtil;
import com.google.gson.Gson;
import com.google.gson.JsonParseException;
import com.google.gson.reflect.TypeToken;
import com.skymobi.handler.SkymobiHandler;
import com.skymobi.message.SkymobiProtocolMessage;
import com.skymobi.message.widget.AddDataTLV;
import com.skymobi.message.widget.AddEditBoxTLV;
import com.skymobi.message.widget.ClearDataTLV;
import com.skymobi.message.widget.CloseWinTLV;
import com.skymobi.message.widget.CreateEditBoxTLV;
import com.skymobi.message.widget.CreateMsgBoxTLV;
import com.skymobi.message.widget.CtrlTLVStructureRequest;
import com.skymobi.message.widget.SendDataTLV;
import com.skymobi.message.widget.ShowPopupMenuTLV;
import com.skymobi.message.widget.ShowWaitingMsgBoxTLV;
import com.skymobi.message.widget.WinType;
import com.skymobi.service.SkymobiService;
import com.skymobi.util.Text;

public class MmochatGmService {
	private static Logger log = LoggerFactory.getLogger(MmochatGmService.class);

	// 客服列表:账号-->gm
	public static Map<String, MmochatGm> gmMap = new ConcurrentHashMap<String, MmochatGm>();

	// 玩家离线，但因客服操作而被加载到内存的玩家-->简称“客服调用玩家”
	public static Map<Integer, MmochatPlayer> gmOptionPlayers = new ConcurrentHashMap<Integer, MmochatPlayer>();

	// 线下角色出售订单
	public static Map<Integer, MmochatRoleDeal> roleDeals = new ConcurrentHashMap<Integer, MmochatRoleDeal>();

	public static ScheduledExecutorService checkUnusedPlayerThread = Executors
			.newScheduledThreadPool(1); // 检查已经不用的客服调用玩家

	private static boolean isStopServerThreadStart = false; // 停服线程是否已经运行
	private static boolean cancelStopServerTag = false; // 中断停服标志
	private static int timeToCancelStopServer = 30; // 还有几秒允许中断停服
	private static boolean isSystemExit = false; // System.exit(0)是否已经调用
	private static Object exitLock = new Object();

	private static Object kufuMsgLock = new Object();

	// 用于记录退出时需要保存数据库的玩家
	public static Map<Integer, MmochatPlayer> saveExitPlayerSqlMap = new ConcurrentHashMap<Integer, MmochatPlayer>();

	// 未处理完成的客服消息
	public static ConcurrentLinkedQueue<MmochatKefuQuestion> kefuMsg = new ConcurrentLinkedQueue<MmochatKefuQuestion>();
	// private static int kefuMsgCount; // 未处理的客服消息数量
	private static final int maxKefuMsgNum = 20000; // 最多保留几条客服消息(包括系统私密玩家消息)

	// 标准客服回答
	public static Map<Integer, MmochatStandardKefuProblem> standardKefuProblems = new ConcurrentHashMap<Integer, MmochatStandardKefuProblem>();

	// 标准客服回答解决的问题数
	public static int standardKefuProblemsOverNum = 0;

	// 人工客服未回答就删除的问题数
	public static int kefuDeleteNum = 0;

	// 玩家的总问题数
	public static int totalKefuMsg = 0;

	// 已处理的问题的总处理时间
	public static long totalDealTime = 0;

	// 已处理的问题的首次回复时间
	public static long totalFirstReplyTime = 0;

	// 已处理完成的问题数量
	public static int finishedKefuCount = 0;

	// 封号原因:roleId-->原因
	public static Map<Integer, String> forbiddenReasons = new ConcurrentHashMap<Integer, String>();

	// 预充值信息:id-->MmochatDelayPay
	public static Map<Integer, MmochatDelayPay> delayPays = new ConcurrentHashMap<Integer, MmochatDelayPay>();

	// 本次总预充值(维护后清0)
	public static int curTotalDelayPay = 0;

	// 预充值的时间点
	public static List<String> delayPayDateList = new ArrayList<String>();

	// 预充值活动期间，进入元宝充值页面的人次
	public static int delayPayShowTimes = 0;

	// 预充值活动期间，进入预充值页面的人次
	public static int delayPayEffectShowTimes = 0;

	// 预充值有效订单数
	public static int delayPayTimes = 0;

	public void init() {
		if (!MmochatMain.openMergeServer) {
			checkUnusedPlayerThread.scheduleWithFixedDelay(
					new CheckUnusedPlayer(), 3, 3, TimeUnit.MINUTES);

			// 加载标准客服问题
			loadStandardKefuProblems();

			// 从数据库加载未处理的客服消息
			String kefuData = null;
			try {
				kefuData = MmochatDao.getKefuQuestion();
			} catch (Exception e) {
				e.printStackTrace();
			}
			if (kefuData != null) {
				Gson gson = new Gson();
				try {
					List<MmochatKefuQuestion> oldKefuMsg = gson.fromJson(
							kefuData,
							new TypeToken<List<MmochatKefuQuestion>>() {
							}.getType());
					if (oldKefuMsg != null) {
						for (MmochatKefuQuestion q : oldKefuMsg) {
							kefuMsg.offer(q);
						}
					}
				} catch (JsonParseException e) {
					e.printStackTrace();
				}
			} else {
				// 数据库尚无记录，新增一条空记录
				try {
					MmochatDao.addNewKefuQuestion();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

			// 从数据库加载所有GM
			List<MmochatGm> gmList;
			try {
				gmList = MmochatDao.getAllGm();
				for (MmochatGm gm : gmList) {
					gmMap.put(gm.getUsername(), gm);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}

			// 加载所有等待受理的历史预充值订单
			loadUnDealedDelayPay();
		}
	}

	public static void addDelayPayDate(String date) {
		delayPayDateList.add(date);
	}

	public static boolean isTodayDelayPayOpen() {
		if (delayPayDateList == null || delayPayDateList.size() == 0) {
			return false;
		}
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		String today = sdf.format(new Date());
		if (delayPayDateList.contains(today)) {
			return true;
		}
		return false;
	}

	// 加载客服标准回答
	public static void loadStandardKefuProblems() {
		try {
			File root = new File("base/kefu");
			File[] files = root.listFiles();
			if (files != null) {
				log.debug("start loading kefuModel.xml...");
				Map<Integer, MmochatStandardKefuProblem> tmp = new ConcurrentHashMap<Integer, MmochatStandardKefuProblem>();
				for (File file : files) {
					if (!file.isFile()) {
						continue;
					}
					DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
							.newInstance();
					DocumentBuilder docBuilder = docBuilderFactory
							.newDocumentBuilder();
					Document doc = docBuilder.parse(file);
					doc.getDocumentElement().normalize();
					NodeList listOfBBS = doc.getElementsByTagName("问题");
					log.debug("客服标准问题 num = " + listOfBBS.getLength());

					for (int s = 0; s < listOfBBS.getLength(); s++) {
						Node firstNpcNode = listOfBBS.item(s);
						if (firstNpcNode.getNodeType() == Node.ELEMENT_NODE) {
							MmochatStandardKefuProblem problem = new MmochatStandardKefuProblem();
							Element firstNpcElement = (Element) firstNpcNode;

							// 读取提问
							{
								NodeList node = firstNpcElement
										.getElementsByTagName("提问");
								String str = node.item(0).getChildNodes().item(
										0).getNodeValue().trim();
								if (str != null) {
									problem.setQuestion(str);
								}
							}

							// 读取提问关键字
							{
								NodeList node = firstNpcElement
										.getElementsByTagName("提问关键字");
								String str = node.item(0).getChildNodes().item(
										0).getNodeValue().trim();
								if (str != null) {
									String[] subs = str.split("、");
									for (String sub : subs) {
										problem.getKeywords().add(sub);
									}
								}
							}

							// 读取回答
							{
								NodeList node = firstNpcElement
										.getElementsByTagName("解答");
								String str = node.item(0).getChildNodes().item(
										0).getNodeValue().trim();
								if (str != null) {
									problem.setAnswer(str);
								}
							}
							tmp.put(problem.getId(), problem);
						}
					}
				}
				standardKefuProblems = tmp;
				log.debug("start load kefuModel.xml ok!");
			}
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	class CheckUnusedPlayer implements Runnable {
		@Override
		public void run() {
			try {
				for (MmochatPlayer me : gmOptionPlayers.values()) {
					if (System.currentTimeMillis() - me.getLatestActiveTime() > 10 * MmochatConstant.MS_PER_MINUTE) {
						// 如果10分钟没有操作，则从缓存中去除
						gmOptionPlayers.remove(me.getRoleId());
					}
				}
				try {
					for (MmochatKefuQuestion q : kefuMsg) {
						if (System.currentTimeMillis() - q.getId() > 10 * MmochatConstant.MS_PER_DAY) {
							// 超过10天的问题就去除掉
							kefuMsg.remove(q);
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}

			try {
				// 角色订单超时检测
				for (MmochatRoleDeal deal : roleDeals.values()) {
					if (deal.getState() != MmochatRoleDealState.交易关闭
							&& deal.getState() != MmochatRoleDealState.出售成功
							&& deal.getState() != MmochatRoleDealState.转号成功
							&& deal.isTimeOut()) {
						deal.setState(MmochatRoleDealState.交易关闭);
						deal.setDealReason("交易超时!");
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}

			// 超时预充值订单
			try {
				for (MmochatDelayPay pay : delayPays.values()) {
					try {
						if (pay.isTimeOut()) {
							delayPays.remove(pay.getId());
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	// 验证GM账号
	public static MmochatGm CheckGmPassword(String username, String password) {
		MmochatGm gm = gmMap.get(username);
		if (gm == null) {
			return null;
		}
		String md5String = MmochatUtil.MD5(password);
		if (md5String != null && gm.getPassword().equals(md5String)) {
			return gm;
		}
		return null;
	}

	// 创建GM账号
	public static String AddGm(String username, String password,
			String trueName, int priority) {
		if (password == null || password.length() == 0) {
			return "密码不能为空";
		}
		MmochatGm gm = gmMap.get(username);
		if (gm != null) {
			return "账号已存在!";
		}
		String md5String = MmochatUtil.MD5(password);
		gm = new MmochatGm();
		gm.setUsername(username);
		gm.setPassword(md5String);
		gm.setPriority(priority);
		gm.setTruename(trueName);

		try {
			MmochatDao.addGm(gm);
		} catch (Exception e) {
			return e.getMessage();
		}
		gmMap.put(username, gm);
		return "创建成功!";
	}

	// 删除GM账号
	public static String DelGm(String username) {
		MmochatGm gm = gmMap.remove(username);
		if (gm == null) {
			return "账号不存在!";
		}
		try {
			MmochatDao.delGm(username);
		} catch (Exception e) {
			return e.getMessage();
		}
		gmMap.remove(username);
		return "删除账号成功!";
	}

	// 修改GM账号
	public static String EditGm(String username, String trueName, int priority) {
		MmochatGm gm = gmMap.get(username);
		if (gm == null) {
			return "账号不存在!";
		}
		try {
			MmochatDao.editGm(trueName, priority, username);
		} catch (Exception e) {
			return e.getMessage();
		}
		gm.setTruename(trueName);
		gm.setPriority(priority);
		return "修改成功!";
	}

	// 修改GM密码
	public static String EditGm(String username, String password) {
		MmochatGm gm = gmMap.get(username);
		if (gm == null) {
			return "账号不存在!";
		}
		String md5String = MmochatUtil.MD5(password);
		try {
			MmochatDao.editGmPwd(md5String, username);
		} catch (Exception e) {
			return e.getMessage();
		}
		gm.setPassword(md5String);
		return "修改成功!";
	}

	// 客服发送私聊消息
	public static void sendKufuPrivateMsg(int roleId, String content,
			boolean needReply) {
		synchronized (kufuMsgLock) {
			sendKufuPrivateMsg(roleId, content, needReply, System
					.currentTimeMillis());
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	// 在连续调用的情况下需要addId，以免id重复
	public static void sendKufuPrivateMsg(int roleId, String content,
			boolean needReply, long id) {
		MmochatKefuQuestion myQuestion = new MmochatKefuQuestion();
		myQuestion.setId(id);
		if (kefuMsg.size() >= maxKefuMsgNum) {
			kefuMsg.poll();
		}
		kefuMsg.offer(myQuestion);
		myQuestion.setRoleId(roleId);
		myQuestion.addContent(content);
		myQuestion.setReplied(true);
		myQuestion.setDealed(true);
		myQuestion.setNeedReply(needReply);

		MmochatPlayer me = MmochatMainService.players.get(roleId);
		if (me != null) {
			// 下发消息
			sendKefuMesboxToPerson(me, myQuestion.getId(), content, needReply);
		}
	}

	public static void saveKufuPrivateMsg(int roleId, String content,
			boolean needReply) {
		synchronized (kufuMsgLock) {
			MmochatKefuQuestion myQuestion = new MmochatKefuQuestion();
			myQuestion.setId(System.currentTimeMillis());
			if (kefuMsg.size() >= maxKefuMsgNum) {
				kefuMsg.poll();
			}
			kefuMsg.offer(myQuestion);
			myQuestion.setRoleId(roleId);
			myQuestion.addContent(content);
			myQuestion.setReplied(true);
			myQuestion.setDealed(true);
			myQuestion.setNeedReply(needReply);
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	// 11.3 提交客服提问
	@SkymobiService
	public SkymobiProtocolMessage handleC_11_3(SkymobiHandler handler,
			Mmochat_11_3C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}
		if (req.getMsg().trim().length() == 0) {
			return MmochatUtil.msgbox(req.getHallState(), "问题不能为空!");
		}

		// 查找是否有标准解答
		String question = req.getMsg();
		int count = 0;
		List<MmochatStandardKefuProblem> okProblems = new ArrayList<MmochatStandardKefuProblem>();
		for (MmochatStandardKefuProblem p : standardKefuProblems.values()) {
			boolean has = false;
			for (String keyWords : p.getKeywords()) {
				if (question.contains(keyWords)) {
					// 提问中有此关键字
					okProblems.add(p);
					has = true;
					break;
				}
			}
			if (has) {
				count++;
				if (count >= 20) {
					break;
				}
			}
		}

		// 先查找是否有此玩家未完结的提问，如果有，则追加到此提问中
		MmochatKefuQuestion myQuestion = null;
		if (okProblems.size() == 0) {
			// 如果有参考答案，则此问题不追加到已有问题
			for (MmochatKefuQuestion q : kefuMsg) {
				if (!q.isReplied() && q.getRoleId() == me.getRoleId()) {
					myQuestion = q;
					break;
				}
			}
		}

		if (myQuestion == null) {
			myQuestion = new MmochatKefuQuestion();
			if (kefuMsg.size() >= maxKefuMsgNum) {
				kefuMsg.poll();
			}
			kefuMsg.offer(myQuestion);
			totalKefuMsg++;
		} else {
			// 重新插入队列
			kefuMsg.remove(myQuestion);
			kefuMsg.offer(myQuestion);
		}

		Calendar cal = Calendar.getInstance();
		java.text.SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm:ss");
		String cdate = sdf.format(cal.getTime());

		String headInfo = "[" + cdate + "]" + me.getName() + "(roleId:"
				+ me.getRoleId() + ")";

		myQuestion.setHeadInfo(headInfo);
		myQuestion.addContent("[问]" + question);
		myQuestion.setRoleId(req.getRoleId());
		myQuestion.setBigMoney((int) me.getBig_money());

		// 有标准回答、下发列表
		if (okProblems.size() > 0) {
			CreateTlvWin tlv = new CreateTlvWin();
			tlv.setWinType(WinType.List);
			tlv.setLeftName("查看");
			tlv.setRightName("返回");
			tlv.setTitle("相似问题");
			tlv.setWinHeight(208);

			tlv
					.addItemEvent(MmochatUtil.wrapColor(
							"若下面问题不是您想问的，则按返回，由客服人工解答", Color.yellow),
							new ClearDataTLV(), new AddDataTLV((int) -1));
			int index = 1;
			for (MmochatStandardKefuProblem p : okProblems) {
				p.addShowTimes();
				String item = index + "、" + p.getQuestion();
				index++;
				tlv.addItemEvent(item, new ClearDataTLV(), new AddDataTLV(
						(int) p.getId()));
			}
			tlv.addLeftTLV(new AddDataTLV((long) myQuestion.getId()));
			tlv.addLeftTLV(new SendDataTLV(MmochatConstant.getClientModuleId(),
					MmochatMain.getModuleInstID(),
					MmochatConstant.MSGCODE_MMOCHAT_C_20_16, (int) me
							.getRoleId()));
			tlv.addLeftTLV(new ShowWaitingMsgBoxTLV());

			tlv.addRightTLV(new ClearDataTLV());
			tlv.addRightTLV(new AddDataTLV((long) myQuestion.getId()));
			tlv.addRightTLV(new SendDataTLV(
					MmochatConstant.getClientModuleId(), MmochatMain
							.getModuleInstID(),
					MmochatConstant.MSGCODE_MMOCHAT_C_20_18, (int) me
							.getRoleId()));
			tlv.addRightTLV(new CloseWinTLV());

			return MmochatUtil.tlvResponse(req.getHallState(), tlv);
		}
		return MmochatUtil.msgbox(req.getHallState(),
				"您的问题已记录，我们会尽快以系统消息的方式答复您!");
	}

	// 20.16 查看标准问题
	@SkymobiService
	public SkymobiProtocolMessage handleC_20_16(SkymobiHandler handler,
			Mmochat_20_16C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}
		if (req.getStandardQuestionId() == -1) {
			return MmochatUtil.msgbox(req.getHallState(),
					"请关闭列表，稍候客服会对您的问题进行人工解答!");
		}
		MmochatStandardKefuProblem p = standardKefuProblems.get(req
				.getStandardQuestionId());
		if (p == null) {
			return MmochatUtil.msgbox(req.getHallState(),
					"您要查看的问题不存在!请关闭列表，稍候客服会对您的问题进行人工解答!");
		}
		p.addHit();
		CreateTlvWin tlv = new CreateTlvWin();
		tlv.setWinType(WinType.Text);
		tlv.setLeftName("完结");
		tlv.setRightName("返回");
		tlv.setTitle(p.getQuestion());
		tlv.setWinHeight(208);
		tlv.addRightTLV(new CloseWinTLV());
		String content = "";
		content += MmochatUtil.wrapColor("[问]", Color.green) + p.getQuestion()
				+ "\n";
		content += MmochatUtil.wrapColor("[答]", Color.green) + p.getAnswer()
				+ "\n\n";
		content += MmochatUtil.wrapColor("如果此回答已经帮您解决了问题，请点击<完结>，否则请返回退出!\n"
				+ "返回退出后，客服会进行人工解答!", Color.yellow);
		tlv.setContent(new Text(content));

		tlv.addLeftTLV(new ClearDataTLV());
		tlv.addLeftTLV(new AddDataTLV((int) me.getRoleId()));
		tlv.addLeftTLV(new AddDataTLV((int) p.getId()));
		tlv.addLeftTLV(new AddDataTLV((long) req.getMyQuestionId()));
		tlv.addLeftTLV(new SendDataTLV(MmochatConstant.getClientModuleId(),
				MmochatMain.getModuleInstID(),
				MmochatConstant.MSGCODE_MMOCHAT_C_20_17, null));
		tlv.addLeftTLV(new CloseWinTLV());

		return MmochatUtil.tlvResponse(req.getHallState(), tlv);
	}

	// 20.17 查看标准问题后完结
	@SkymobiService
	public SkymobiProtocolMessage handleC_20_17(SkymobiHandler handler,
			Mmochat_20_17C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}

		long questionId = req.getMyQuestionId();
		MmochatKefuQuestion curQuestion = null;
		for (MmochatKefuQuestion question : kefuMsg) {
			if (question.getId() == questionId) {
				curQuestion = question;
				break;
			}
		}
		if (curQuestion == null) {
			return null;
		}
		kefuMsg.remove(curQuestion);
		MmochatStandardKefuProblem p = standardKefuProblems.get(req
				.getStandardQuestionId());
		if (p != null) {
			p.addFinishTimes();
		}
		standardKefuProblemsOverNum++;
		return null;
	}

	// 11.6 提交卖号提问
	@SkymobiService
	public SkymobiProtocolMessage handleC_11_6(SkymobiHandler handler,
			Mmochat_11_6C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}
		if (req.getMsg().trim().length() == 0) {
			return MmochatUtil.msgbox(req.getHallState(), "发送内容不能为空!");
		}
		if (me.getLevel() != 0) {
			return MmochatUtil.msgbox(req.getHallState(),
					"您必须重新创建一个0级角色，再发送此内容!");
		}

		Calendar cal = Calendar.getInstance();
		java.text.SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm:ss");
		String cdate = sdf.format(cal.getTime());

		String headInfo = "[" + cdate + "]" + me.getName() + "(roleId:"
				+ me.getRoleId() + ")";
		MmochatKefuQuestion myQuestion = new MmochatKefuQuestion();
		if (kefuMsg.size() >= maxKefuMsgNum) {
			kefuMsg.poll();
		}
		kefuMsg.offer(myQuestion);

		myQuestion.setHeadInfo(headInfo);
		if (req.getIndex() == 1) {
			myQuestion.addContent("[卖号]" + req.getMsg());
		} else if (req.getIndex() == 2) {
			myQuestion.addContent("[卖物品]" + req.getMsg());
		} else {
			myQuestion.addContent("[其它]" + req.getMsg());
		}
		myQuestion.setRoleId(req.getRoleId());
		myQuestion.setBigMoney((int) me.getBig_money());

		return MmochatUtil.msgbox(req.getHallState(),
				"您的出售消息已提交!建议您打客服电话057185222407，让客服人员现在帮您操作。");
	}

	// 获取未回复的客服问题
	public static List<MmochatKefuQuestion> getKefuMsg() {
		Object[] msgs = kefuMsg.toArray();
		List<MmochatKefuQuestion> questions = new ArrayList<MmochatKefuQuestion>();
		for (Object obj : msgs) {
			MmochatKefuQuestion q = (MmochatKefuQuestion) obj;
			if (!q.isReplied()) {
				questions.add(q);
			}
		}
		return questions;
	}

	// 回复玩家提问
	public static void sendKefuAnswer(long questionId, int roleId,
			String content) {
		MmochatKefuQuestion question = null;
		for (MmochatKefuQuestion q : kefuMsg) {
			if (q.getId() == questionId) {
				question = q;
				break;
			}
		}
		if (question == null) {
			// 问题已经不存在
			return;
		}

		MmochatPlayer me = MmochatMainService.players.get(roleId);
		if (me != null) {
			// 下发回复
			sendKefuMesboxToPerson(me, questionId, content, true);
		}
		if (!question.isDealed()) {
			// 第一次回答
			question.setFirstReplyTime(System.currentTimeMillis());
		}
		question.addContent(content);
		question.setReplied(true);
		question.setDealed(true);
		question.setNeedReply(true);
	}

	// 删除玩家提问
	public static void deleteKefuQuestion(long questionId) {
		for (MmochatKefuQuestion question : kefuMsg) {
			if (question.getId() == questionId) {
				if (!question.isDealed()) {
					kefuDeleteNum++;
				} else {
					// 已经回答过，现在删除，则视为完结
					totalFirstReplyTime += Math.max(0, question
							.getFirstReplyTime()
							- question.getCreateTime());
					totalDealTime += System.currentTimeMillis()
							- question.getCreateTime();
					finishedKefuCount++;
				}
				kefuMsg.remove(question);
				break;
			}
		}
	}

	// needReply:是否需要玩家回复
	public static void sendKefuMesboxToPerson(MmochatPlayer me,
			long questionId, String msg, boolean needReply) {
		if (me == null || msg == null) {
			return;
		}
		String answerContent = MmochatUtil.wrapColor("客服消息:", Color.magenta)
				+ msg;
		CreateMsgBoxTLV msgbox = new CreateMsgBoxTLV();
		msgbox.setContent(new Text(answerContent));
		if (needReply) {
			msgbox.setLeftName("回复");
			msgbox.setRightName("完结");

			// 左键回复
			CreateEditBoxTLV edit = new CreateEditBoxTLV();
			edit.setTitle("请输入回复内容!");
			edit.setLeftName("回复");
			edit.setRightName("取消");
			edit.setContentLenMax(50);
			edit.setBoxType(CreateEditBoxTLV.TYPE_LOCAL);
			edit.setInputType(CreateEditBoxTLV.INPUT_ANY << 4);
			edit.addLeftTLV(new AddDataTLV((int) me.getRoleId()));
			edit.addLeftTLV(new AddDataTLV((long) questionId));
			edit.addLeftTLV(new AddEditBoxTLV());
			edit.addLeftTLV(new SendDataTLV(
					MmochatConstant.getClientModuleId(), MmochatMain
							.getModuleInstID(),
					MmochatConstant.MSGCODE_MMOCHAT_C_11_4, null));

			edit.addRightTLV(new AddDataTLV((int) me.getRoleId()));
			edit.addRightTLV(new AddDataTLV((long) questionId));
			edit.addRightTLV(new SendDataTLV(MmochatConstant
					.getClientModuleId(), MmochatMain.getModuleInstID(),
					MmochatConstant.MSGCODE_MMOCHAT_C_11_4, (short) 0));

			msgbox.addLeftTLV(new ClearDataTLV());
			msgbox.addLeftTLV(edit);
		} else {
			msgbox.setRightName("关闭");
		}

		// 右键完结
		msgbox.addRightTLV(new ClearDataTLV());
		msgbox.addRightTLV(new AddDataTLV((int) me.getRoleId()));
		msgbox.addRightTLV(new AddDataTLV((long) questionId));
		msgbox.addRightTLV(new SendDataTLV(MmochatConstant.getClientModuleId(),
				MmochatMain.getModuleInstID(),
				MmochatConstant.MSGCODE_MMOCHAT_C_11_4, (short) 0));

		CtrlTLVStructureRequest pack = new CtrlTLVStructureRequest(0, msgbox);
		pack.setSrcId(MmochatMain.getModuleInstID());
		pack.setDstId(MmochatConstant.getClientModuleId());
		pack.setMsgCode(MmochatConstant.MSGCODE_MMOCHAT_S_10_20);
		MmochatUtil.sendCommonPack(me, pack);
	}

	// 11.4 玩家追问
	@SkymobiService
	public SkymobiProtocolMessage handleC_11_4(SkymobiHandler handler,
			Mmochat_11_4C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}
		long questionId = req.getQuestionId();
		String content = req.getMsg();
		MmochatKefuQuestion curQuestion = null;
		for (MmochatKefuQuestion question : kefuMsg) {
			if (question.getId() == questionId) {
				curQuestion = question;
				break;
			}
		}
		if (content == null || content.length() == 0) {
			// 问题完结
			if (curQuestion != null) {
				// 已经回答过，现在删除，则视为完结
				totalFirstReplyTime += Math.max(0, curQuestion
						.getFirstReplyTime()
						- curQuestion.getCreateTime());
				totalDealTime += System.currentTimeMillis()
						- curQuestion.getCreateTime();
				finishedKefuCount++;
				kefuMsg.remove(curQuestion);
			}
			return null;
		} else {
			Calendar cal = Calendar.getInstance();
			java.text.SimpleDateFormat sdf = new SimpleDateFormat(
					"MM-dd HH:mm:ss");
			String cdate = sdf.format(cal.getTime());
			String headInfo = "[" + cdate + "]" + me.getName() + "(roleId:"
					+ me.getRoleId() + ")";

			if (curQuestion == null) {
				// 可能由于玩家经过很久才上线追问，原问题已经被删除，需要重新添加此问题
				MmochatKefuQuestion msg = new MmochatKefuQuestion();
				msg.setHeadInfo(headInfo);
				msg.addContent("[问]" + content);
				msg.setRoleId(req.getRoleId());
				msg.setBigMoney((int) me.getBig_money());
				msg.setReplied(false);

				if (kefuMsg.size() >= maxKefuMsgNum) {
					kefuMsg.poll();
				}
				kefuMsg.offer(msg);
			} else {
				// 追加提问
				curQuestion.setHeadInfo(headInfo);
				curQuestion.addContent("[问]" + content);
				curQuestion.setBigMoney((int) me.getBig_money());
				curQuestion.setReplied(false);
			}
			return MmochatUtil.msgbox(req.getHallState(),
					"您的回复已记录，我们会尽快以系统消息的方式答复您!");
		}
	}

	// 读取角色信息
	public static MmochatPlayer getRoleInfoById(int roleId) {
		MmochatPlayer me = MmochatMainService.getRoleFromBuffer(roleId);
		if (me == null) {
			try {
				me = MmochatDao.getRoleIncludeDeleted(roleId);
			} catch (EmptyResultDataAccessException e) {
			} catch (Exception e) {
				e.printStackTrace();
			}
			if (me != null) {
				gmOptionPlayers.put(me.getRoleId(), me);
			}
		}
		return me;
	}

	// 读取角色信息
	public static MmochatPlayer getRoleInfoByName(String roleName) {
		Integer roleId = MmochatMainService.nameMap.get(roleName);
		if (roleId != null) {
			return getRoleInfoById(roleId);
		} else {
			MmochatPlayer me = null;
			try {
				me = MmochatDao.getRoleByName(roleName);
			} catch (EmptyResultDataAccessException e) {
			} catch (Exception e) {
				e.printStackTrace();
			}
			if (me != null) {
				gmOptionPlayers.put(me.getRoleId(), me);
			}
			return me;
		}
	}

	// 增加角色道行
	public static boolean addRoleDao(int roleId, int add) {
		if (add == 0) {
			return true;
		}
		try {
			MmochatDao.addRoleDao(roleId, add);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		MmochatPlayer me = MmochatMainService.getRoleFromBuffer(roleId);
		if (me != null) {
			me.addDao(add);
		}
		return true;
	}

	// 增加角色经验
	public static boolean addRoleExp(int roleId, int add) {
		if (add == 0) {
			return true;
		}
		try {
			MmochatDao.addRoleExp(roleId, add);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		MmochatPlayer me = MmochatMainService.getRoleFromBuffer(roleId);
		if (me != null) {
			me.addExpWithoutUplevel(add);
		}
		return true;
	}

	// 增加角色战绩
	public static boolean addRoleZhanJi(int roleId, int add) {
		if (add == 0) {
			return true;
		}
		try {
			MmochatDao.addRoleZhanJi(roleId, add);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		MmochatPlayer me = MmochatMainService.getRoleFromBuffer(roleId);
		if (me != null) {
			me.addZhanji(add);
		}
		return true;
	}

	// 增加角色金钱
	public static boolean addRoleSmallMoney(int roleId, int add) {
		if (add == 0) {
			return true;
		}
		try {
			MmochatDao.addRoleSmallMoney(roleId, add);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		MmochatPlayer me = MmochatMainService.getRoleFromBuffer(roleId);
		if (me != null) {
			me.addAndUpdateSmall_money(add);
			if (add > 0) {
				MmochatStatisticsService.addSmallMoneyEarn(
						MmochatSmallMoneyEarnType.客服增加游戏币, add);
			} else {
				MmochatStatisticsService.addSmallMoneyCost(
						MmochatSmallMoneyCostType.客服扣除游戏币, add);
			}
		}
		return true;
	}

	// 增加角色元宝
	public static boolean addRoleBigMoney(int roleId, int add) {
		if (add == 0) {
			return true;
		}
		try {
			MmochatDao.addRoleBigMoney(roleId, add);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		MmochatPlayer me = MmochatMainService.getRoleFromBuffer(roleId);
		if (me != null) {
			me.addBig_money(add);
			if (add > 0) {
				MmochatStatisticsService.addBigMoneyEarn(
						MmochatBigMoneyEarnType.客服增加元宝, add);
			} else {
				MmochatStatisticsService.addBigMoneyCost(
						MmochatBigMoneyCostType.客服扣除元宝, add);
			}
		}
		return true;
	}

	// 增加角色药品
	@SuppressWarnings("unchecked")
	public static boolean addRoleDrug(int roleId, MmochatDrugType drugType,
			boolean canDeal, int num) {
		if (num <= 0) {
			return true;
		}
		if (drugType == null) {
			return false;
		}
		MmochatPlayer me = getRoleInfoById(roleId);
		if (me == null) {
			return false;
		}
		if (me.calRestPackageSpace(drugType, true, canDeal) < num) {
			return false;
		}
		synchronized (me) {
			Map<Integer, MmochatPackageGrid> bak = (Map<Integer, MmochatPackageGrid>) MmochatUtil
					.deepClone(me.getMyPackage(),
							new TypeToken<Map<Integer, MmochatPackageGrid>>() {
							}.getType());
			MmochatCommonObject obj = new MmochatDrug();
			obj.setDrugType(drugType);
			obj.setCanDeal(canDeal);
			obj.setOverlapNum(num);
			me.addObjectToPackage(obj);
			try {
				MmochatDao.updateMyPackage(me);
			} catch (Exception e) {
				e.printStackTrace();
				me.setMyPackage(bak);
				return false;
			}
		}
		return true;
	}

	// 增加角色材料
	@SuppressWarnings("unchecked")
	public static boolean addRoleMaterial(int roleId,
			MmochatMaterialType materialType, boolean canDeal, int num) {
		if (num <= 0) {
			return true;
		}
		if (materialType == null) {
			return false;
		}
		MmochatPlayer me = getRoleInfoById(roleId);
		if (me == null) {
			return false;
		}
		if (me.calRestPackageSpace(materialType, true, canDeal) < num) {
			return false;
		}
		synchronized (me) {
			Map<Integer, MmochatPackageGrid> bak = (Map<Integer, MmochatPackageGrid>) MmochatUtil
					.deepClone(me.getMyPackage(),
							new TypeToken<Map<Integer, MmochatPackageGrid>>() {
							}.getType());
			MmochatCommonObject obj = new MmochatMaterial();
			obj.setMaterialType(materialType);
			obj.setCanDeal(canDeal);
			obj.setOverlapNum(num);
			me.addObjectToPackage(obj);
			try {
				MmochatDao.updateMyPackage(me);
			} catch (Exception e) {
				e.printStackTrace();
				me.setMyPackage(bak);
				return false;
			}
		}
		return true;
	}

	// 增加角色 道具
	@SuppressWarnings("unchecked")
	public static boolean addRoleProp(int roleId, MmochatPropType propType,
			boolean canDeal, int num) {
		if (num <= 0) {
			return true;
		}
		if (propType == null) {
			return false;
		}
		MmochatPlayer me = getRoleInfoById(roleId);
		if (me == null) {
			return false;
		}
		if (me.calRestPackageSpace(propType, true, canDeal) < num) {
			return false;
		}
		synchronized (me) {
			Map<Integer, MmochatPackageGrid> bak = (Map<Integer, MmochatPackageGrid>) MmochatUtil
					.deepClone(me.getMyPackage(),
							new TypeToken<Map<Integer, MmochatPackageGrid>>() {
							}.getType());
			if (propType.isCanOverLap()) {
				MmochatCommonObject obj = new MmochatProp(propType);
				obj.setCanDeal(canDeal);
				obj.setOverlapNum(num);
				me.addObjectToPackage(obj);
			} else {
				for (int i = 0; i < num; i++) {
					MmochatCommonObject obj = new MmochatProp(propType);
					obj.setCanDeal(canDeal);
					obj.setOverlapNum(1);
					me.addObjectToPackage(obj);
				}
			}
			try {
				MmochatDao.updateMyPackage(me);
			} catch (Exception e) {
				e.printStackTrace();
				me.setMyPackage(bak);
				return false;
			}
		}
		return true;
	}

	// 增加角色法宝
	@SuppressWarnings("unchecked")
	public static boolean addRoleSuperMachine(int roleId,
			MmochatSuperMachineType machineType, int machineLevel,
			int machineValue, boolean canDeal, int num) {
		if (num <= 0) {
			return true;
		}
		if (machineType == null || machineValue < 0) {
			return false;
		}
		MmochatPlayer me = getRoleInfoById(roleId);
		if (me == null) {
			return false;
		}
		if (me.calRestPackageSpace(machineType, false, canDeal) < num) {
			return false;
		}
		synchronized (me) {
			Map<Integer, MmochatPackageGrid> bak = (Map<Integer, MmochatPackageGrid>) MmochatUtil
					.deepClone(me.getMyPackage(),
							new TypeToken<Map<Integer, MmochatPackageGrid>>() {
							}.getType());
			int speedLevel, flyLevel;
			speedLevel = Math.min(MmochatCommonObject.flyMachineMaxSpeedLevel,
					machineLevel);
			flyLevel = Math.max(0, machineLevel
					- MmochatCommonObject.flyMachineMaxSpeedLevel);
			flyLevel = Math.min(MmochatCommonObject.flyMachineMaxFlyLevel,
					flyLevel);
			for (int i = 0; i < num; i++) {
				MmochatCommonObject obj = new MmochatSuperMachine(machineType);
				obj.setCanDeal(canDeal);
				obj.setOverlapNum(1);
				obj.setFlyMachineSpeedLevel(speedLevel);
				obj.setFlyMachineFlyLevel(flyLevel);
				obj.setFlyMachineCanUseTotalValue(machineValue);
				obj.setFlyMachineCanUseValue(machineValue);
				me.addObjectToPackage(obj);
			}
			try {
				MmochatDao.updateMyPackage(me);
			} catch (Exception e) {
				e.printStackTrace();
				me.setMyPackage(bak);
				return false;
			}
		}
		return true;
	}

	// 增加角色随机装备
	@SuppressWarnings("unchecked")
	public static boolean addRoleRandomEquip(int roleId,
			MmochatEquipType equipType, int equipLevel,
			MmochatEquipQualityType equipQuality, boolean canDeal, int num) {
		if (num <= 0) {
			return true;
		}
		if (equipType == null || equipQuality == null) {
			return false;
		}
		MmochatPlayer me = getRoleInfoById(roleId);
		if (me == null) {
			return false;
		}
		if (me.getPackageSpaceNum() < num) {
			return false;
		}
		synchronized (me) {
			Map<Integer, MmochatPackageGrid> bak = (Map<Integer, MmochatPackageGrid>) MmochatUtil
					.deepClone(me.getMyPackage(),
							new TypeToken<Map<Integer, MmochatPackageGrid>>() {
							}.getType());
			for (int i = 0; i < num; i++) {
				MmochatCommonObject obj = MmochatEquipService
						.createRandomEquip(true, equipType, equipLevel,
								equipQuality);
				obj.setCanDeal(canDeal);
				obj.setOverlapNum(1);
				me.addObjectToPackage(obj);
			}
			try {
				MmochatDao.updateMyPackage(me);
			} catch (Exception e) {
				e.printStackTrace();
				me.setMyPackage(bak);
				return false;
			}
		}
		return true;
	}

	// 增加角色等级(不能减)
	public static boolean addRoleLevel(int roleId, int add) {
		if (add == 0) {
			return true;
		}
		if (add < 0) {
			return false;
		}
		MmochatPlayer me = MmochatMainService.getRoleFromBuffer(roleId);
		if (me != null) {
			me.addLevelAndAttr(add);
			try {
				MmochatDao.addRoleLevelAndAttr(me);
			} catch (Exception e) {
				e.printStackTrace();
				return false;
			}
			return true;
		}
		return false;
	}

	// 增加角色奖券
	public static boolean addRoleLottery(int roleId, int add) {
		if (add == 0) {
			return true;
		}
		try {
			MmochatDao.addRoleLottery(roleId, add);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		MmochatPlayer me = MmochatMainService.getRoleFromBuffer(roleId);
		if (me != null) {
			me.addLottery(add);
		}
		return true;
	}

	// 增加角色宠物(满成长)到仓库
	public static boolean addRoleStoredPet(int roleId,
			MmochatRoleType roleType, MmochatPetType petType, int petLevel,
			long dao) {
		if (roleType == null || petType == null || petLevel < 0
				|| petLevel > MmochatConstant.maxLevel || dao < 0
				|| dao > Integer.MAX_VALUE) {
			return false;
		}
		MmochatMonster monster = MmochatPetService.monsterBaseAttrData
				.get(roleType);
		if (monster == null) {
			return false;
		}
		MmochatPet pet = new MmochatPet(monster.getLevel());
		pet.setRoleType(monster.getRoleType());
		pet.setFamily(monster.getFamily());
		pet.setBmpType(monster.getBmpType());
		pet.setPetType(petType);
		pet.setLevel(petLevel);
		MmochatPetService.setRandPetGrown(monster, pet, 0, 0);
		pet.setAttack_point(petLevel);
		pet.setSprit_point(petLevel);
		pet.setBlood_point(petLevel);
		pet.setSpeed_point(petLevel);
		pet.setSpace_point(petLevel * 4);
		pet.setDao((int) dao);
		// 根据等级配置技能
		if (petLevel >= MmochatConstant.monsterSkill1LevelNeed) {
			MmochatSkillType skillType = null;
			switch (pet.getFamily()) {
			case 阐教:
				skillType = MmochatSkillType.雷电交加;
				break;
			case 人教:
				skillType = MmochatSkillType.寒冰利剑;
				break;
			case 截教:
				skillType = MmochatSkillType.焚心蚀骨;
				break;
			default:
				break;
			}
			if (skillType != null) {
				if (pet.getSkills().get(skillType) == null) {
					MmochatSkill skill = new MmochatSkill();
					skill.setType(skillType);
					pet.getSkills().put(skillType, skill);
				}
			}
		}
		if (petLevel >= MmochatConstant.monsterSkill2LevelNeed) {
			MmochatSkillType skillType = null;
			switch (pet.getFamily()) {
			case 阐教:
				skillType = MmochatSkillType.飞云掣电;
				break;
			case 人教:
				skillType = MmochatSkillType.水漫金山;
				break;
			case 截教:
				skillType = MmochatSkillType.毒龙双飞;
				break;
			default:
				break;
			}
			if (skillType != null) {
				if (pet.getSkills().get(skillType) == null) {
					MmochatSkill skill = new MmochatSkill();
					skill.setType(skillType);
					pet.getSkills().put(skillType, skill);
				}
			}
		}
		pet.setCurBlood(pet.getTotalBlood());
		pet.setCurSprit(pet.getTotalSprit());

		// 将宠物添加到玩家宠物仓库
		MmochatPlayer me = getRoleInfoById(roleId);
		if (me == null) {
			return false;
		}
		me.getStoredPets().put(pet.getId(), pet);
		try {
			MmochatDao.updateStorePet(me);
		} catch (Exception e) {
			e.printStackTrace();
			me.getStoredPets().remove(pet.getId());
			return false;
		}
		return true;
	}

	// 增加角色抽奖次数
	public static boolean addRoleAwardTimes(int roleId, int add) {
		if (add == 0) {
			return true;
		}
		try {
			MmochatDao.addRoleAwardTimes(roleId, add);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		MmochatPlayer me = MmochatMainService.getRoleFromBuffer(roleId);
		if (me != null) {
			me.addRest_award_times(add);
		}
		return true;
	}

	// 停服
	public static boolean stopServer(final String stopMsg) {
		synchronized (gmMap) {
			if (isStopServerThreadStart) {
				// 停服线程已经启动
				return false;
			} else {
				isStopServerThreadStart = true;
			}
		}
		Thread exitThread = new Thread() {
			public void run() {
				try {
					// 30秒内可以取消停服操作
					timeToCancelStopServer = 30;
					for (int sec = 0; sec < 30; sec++) {
						if (cancelStopServerTag) {
							isStopServerThreadStart = false;
							cancelStopServerTag = false;
							timeToCancelStopServer = 30;
							return;
						}
						try {
							Thread.sleep(1000);
							timeToCancelStopServer--;
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}

					// 15分钟后关闭服务器
					MmochatFriendService
							.sendSystemMsgToAllByFriendMessage("服务器即将维护重启，"
									+ "系统频道每隔1分钟播报一次停服倒计时，请作好下线准备!" + stopMsg);
					for (int min = 10; min > 1; min--) {
						MmochatChatService.sendSystemMsg("服务器将在" + min
								+ "分钟后停机维护..." + stopMsg);
						MmochatChatService.sendSystemMsg("服务器将在" + min
								+ "分钟后停机维护..." + stopMsg);
						try {
							Thread.sleep(60000);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}

					// 1分钟后关闭服务器
					for (int sec = 60; sec > 10; sec -= 10) {
						MmochatChatService.sendSystemMsg("服务器将在" + sec
								+ "秒后停机维护...");
						try {
							Thread.sleep(10000);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
					for (int sec = 10; sec > 0; sec -= 2) {
						MmochatChatService.sendSystemMsg("服务器将在" + sec
								+ "秒后停机维护...");
						try {
							Thread.sleep(2000);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
					MmochatChatService.sendSystemMsg("服务器正在维护中，当前服务器不再响应任何操作。"
							+ stopMsg);
					exitServer(stopMsg);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		};
		cancelStopServerTag = false;
		exitThread.start();
		return true;
	}

	// 取消停服
	public static boolean cancelStopServer() {
		if (isStopServerThreadStart) {
			if (timeToCancelStopServer > 0 && !cancelStopServerTag) {
				cancelStopServerTag = true;
				return true;
			}
		}
		return false;
	}

	// 是否正在停服中
	public static boolean isStoppingServer() {
		return isStopServerThreadStart;
	}

	// 还有几秒可以取消停服
	public static int getTimeToCancelStopServer() {
		return timeToCancelStopServer;
	}

	public static boolean isSystemExit() {
		return isSystemExit;
	}

	// 立即停服
	public static void stopServerImmediately(String stopMsg) {
		exitServer(stopMsg);
	}

	// 正常停服调用
	public static void exitServer(String stopMsg) {
		synchronized (exitLock) {
			if (isSystemExit) {
				return;
			} else {
				isSystemExit = true;
			}
		}
		if (stopMsg == null) {
			stopMsg = "本区维护中!";
		}
		System.out.println("------exitServer-----");

		long t;
		// 通知列表服务器进入维护状态
		System.out.println("1、通知列表服务器进入维护状态");
		t = System.currentTimeMillis();
		try {
			Mmochat_ServerStateMessage pack = new Mmochat_ServerStateMessage();
			pack.setInstanceId(MmochatMain.getModuleInstID());
			pack.setState(MmochatServerStateType.维护中);
			pack.setStateMsg(stopMsg);
			SkymobiHandler handle = MmochatMainService.getCommonHandler();
			if (handle != null) {
				handle.asyncPushSkymobiModuleMessage(pack, null);
			}
		} catch (Exception e2) {
			e2.printStackTrace();
		}

		// 清空需要保存数据库的用户队列，统一在退出时进行保存
		MmochatBattleService.needToSaveBattleSqlPlayerQueue.clear();
		MmochatTaskService.needToSaveTaskSqlPlayerQueue.clear();
		MmochatPropService.needToSavePropSqlPlayerQueue.clear();
		MmochatMainService.needToSaveLeaveGameSqlPlayerMap.clear();

		// 所有内存中的角色
		List<MmochatPlayer> onlinePlayers = new ArrayList<MmochatPlayer>();
		try {
			onlinePlayers.addAll(MmochatMainService.players.values());
			onlinePlayers.addAll(MmochatMainService.offlinePlayers.values());
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		t = System.currentTimeMillis() - t;
		System.out.println("耗时:" + t + "ms");

		// 保存守护神道行奖励
		System.out.println("2、保存守护神道行奖励和门派王者");
		t = System.currentTimeMillis();
		try {
			MmochatChenHaoType[] chenhaoList = MmochatChenHaoType
					.getMapGuiderChenhaoList();
			for (MmochatMapGuiderData guider : MmochatMapGuiderService.guiderPositions
					.values()) {
				if (guider != null) {
					if (guider.isOnDudy() && guider.getRoleList().size() > 0) {
						int addDao = guider.getDao();
						if (addDao == 0) {
							continue;
						}
						for (Integer roleId : guider.getRoleList()) {
							// 如果旧的守护神存在，则结算道行奖励
							MmochatPlayer me = MmochatGmService
									.getRoleInfoById(roleId);
							if (me != null) {
								int dao = MmochatBattleService.getRealDao(me,
										addDao);
								me.addDao(dao);
								// 称号扣除
								for (MmochatChenHaoType chenhaoType : chenhaoList) {
									me.getChenHaoMap().remove(chenhaoType);
								}
								try {
									MmochatDao.addRoleDaoAndUpdateChenhao(
											roleId, dao, me.getGson_chenhao());
								} catch (Exception e) {
									e.printStackTrace();
								}
							}
						}
					}
					guider.setOnDudy(false);
					guider.getNpcList().clear();
					guider.getRoleList().clear();
				}
			}
		} catch (Exception e2) {
			e2.printStackTrace();
		}

		// 处理王者称号
		try {
			MmochatChenHaoType[] chenhaoList = MmochatChenHaoType
					.getFamilyChenhaoList();
			for (MmochatMapGuiderData guider : MmochatMapGuiderService.familyGuiderPositions
					.values()) {
				if (guider != null) {
					if (guider.isOnDudy() && guider.getRoleList().size() > 0) {
						int addDao = guider.getDao();
						if (addDao == 0) {
							continue;
						}
						for (Integer roleId : guider.getRoleList()) {
							// 如果旧的王者存在，则结算道行奖励
							MmochatPlayer me = MmochatGmService
									.getRoleInfoById(roleId);
							if (me != null) {
								int dao = MmochatBattleService.getRealDao(me,
										addDao);
								me.addDao(dao);
								// 称号扣除
								for (MmochatChenHaoType chenhaoType : chenhaoList) {
									me.getChenHaoMap().remove(chenhaoType);
								}
								try {
									MmochatDao.addRoleDaoAndUpdateChenhao(
											roleId, dao, me.getGson_chenhao());
								} catch (Exception e) {
									e.printStackTrace();
								}
							}
						}
					}
					guider.setOnDudy(false);
					guider.getNpcList().clear();
					guider.getRoleList().clear();
				}
			}
		} catch (Exception e2) {
			e2.printStackTrace();
		}
		t = System.currentTimeMillis() - t;
		System.out.println("耗时:" + t + "ms");

		System.out.println("3、处理镇妖塔称号");
		t = System.currentTimeMillis();
		// 处理镇妖塔称号
		try {
			MmochatTowerService.delAllTowerChenhao();
		} catch (Exception e2) {
			e2.printStackTrace();
		}
		t = System.currentTimeMillis() - t;
		System.out.println("耗时:" + t + "ms");

		System.out.println("4、保存序列号");
		t = System.currentTimeMillis();
		// 保存序列号
		try {
			MmochatDao.updateSerial(MmochatTempNpc.getCurBossId(),
					MmochatTempTask.getCurTaskId());
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		t = System.currentTimeMillis() - t;
		System.out.println("耗时:" + t + "ms");

		// 将所有玩家踢出游戏
		// System.out.println("3、将所有玩家踢出游戏，但不保存数据库");
		// try {
		// for (MmochatPlayer me : MmochatMainService.players.values()) {
		// try {
		// me.stopDeal();
		// MmochatUtil.sendCommonPack(me,
		// new Mmochat_ClientVersionError());
		// } catch (Exception e) {
		// e.printStackTrace();
		// }
		// }
		// } catch (Exception e) {
		// e.printStackTrace();
		// }

		// 保存每日数据
		System.out.println("5、保存每日数据");
		t = System.currentTimeMillis();
		try {
			MmochatStatisticsService.saveDailyStatisticsToSql();
		} catch (Exception e1) {
			System.out.println(e1.getMessage());
			e1.printStackTrace();
		}
		t = System.currentTimeMillis() - t;
		System.out.println("耗时:" + t + "ms");

		// 处理角色订单
		System.out.println("6、关闭角色订单");
		t = System.currentTimeMillis();
		try {
			for (MmochatRoleDeal deal : roleDeals.values()) {
				if (deal.getState() == MmochatRoleDealState.等待支付封1小时
						|| deal.getState() == MmochatRoleDealState.已支付封5天) {
					// 解封角色
					try {
						MmochatDao.forbiddenRole(System.currentTimeMillis(),
								deal.getSellRoleId());
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		} catch (Exception e1) {
			System.out.println(e1.getMessage());
			e1.printStackTrace();
		}
		t = System.currentTimeMillis() - t;
		System.out.println("耗时:" + t + "ms");

		saveExitPlayerSqlMap.clear();
		for (MmochatPlayer me : onlinePlayers) {
			try {
				me.stopDeal();
			} catch (Exception e) {
				e.printStackTrace();
			}
			saveExitPlayerSqlMap.put(me.getRoleId(), me);
		}
		onlinePlayers = new ArrayList<MmochatPlayer>(saveExitPlayerSqlMap
				.values());

		// 取消石头剪刀布比赛，退还资金
		System.out.println("7、取消石头剪刀布比赛，退还资金");
		t = System.currentTimeMillis();
		try {
			Map<Integer, Integer> totalMoney = new ConcurrentHashMap<Integer, Integer>();// roleId-->addMoney
			Map<Integer, Integer> betMoney = new ConcurrentHashMap<Integer, Integer>();// roleId-->addMoney
			for (MmochatStoneBet bet : MmochatPlayerBetService.stoneBets
					.values()) {
				try {
					if (bet != null
							&& bet.getState() == MmochatStoneBetState.等待对手) {
						synchronized (bet) {
							if (bet.getState() == MmochatStoneBetState.等待对手) {
								bet.setState(MmochatStoneBetState.比赛取消);
							} else {
								continue;
							}
						}
						MmochatPlayer me = saveExitPlayerSqlMap.get(bet
								.getSendRoleId());
						if (me != null) {
							// 此用户在内存中
							me.addSmall_money(bet.getMoney());
						} else {
							// 不在内存中，另外保存数据库
							Integer money = betMoney.get(bet.getSendRoleId());
							if (money == null) {
								money = 0;
							}
							money += bet.getMoney();
							betMoney.put(bet.getSendRoleId(), money);
						}

						Integer m = totalMoney.get(bet.getSendRoleId());
						if (m == null) {
							m = 0;
						}
						m += bet.getMoney();
						totalMoney.put(bet.getSendRoleId(), m);
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

			for (Entry<Integer, Integer> entry : betMoney.entrySet()) {
				try {
					Integer roleId = entry.getKey();
					Integer addMoney = entry.getValue();
					if (addMoney == 0) {
						continue;
					}
					for (int s = 0; s < 20; s++) {
						try {
							MmochatDao.addRoleSmallMoney(roleId, addMoney);
							break;
						} catch (Exception e) {
							System.out.println("保存玩家(ID:" + roleId
									+ ")退还石头比赛资金" + addMoney + "失败，第" + (s + 1)
									+ "次/20重试!");
							try {
								int wait = 1000 + s * 500;
								Thread.sleep(wait);
							} catch (Exception e1) {
							}
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

			// 给所有要退钱的人发系统消息
			try {
				for (Entry<Integer, Integer> entry : totalMoney.entrySet()) {
					Integer roleId = entry.getKey();
					Integer addMoney = entry.getValue();
					if (addMoney == 0) {
						continue;
					}
					String content = "由于服务器维护，您在维护前发布的"
							+ MmochatUtil.wrapColor("石头剪刀布比赛已经全部取消",
									Color.green) + "，未开始的比赛的金额全部退还给您，一共是:"
							+ MmochatUtil.getColorMoney(addMoney)
							+ "文钱，请在包裹查收!";
					saveKufuPrivateMsg(roleId, content, false);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}

			// 写记录
			try {
				List<MmochatStoneBet> list = new ArrayList<MmochatStoneBet>(
						MmochatPlayerBetService.recordBets.values());
				String info = "";
				for (MmochatStoneBet bet : list) {
					// 例如:s123|k124|主办方胜|20000|小胡|小明
					info += "s" + bet.getSendRoleId() + "|k"
							+ bet.getKickRoleId() + "|";
					info += bet.getResult().toString() + "|"
							+ bet.getMoney() + "|";
					info += bet.getSendName() + "|" + bet.getKickName();
					info += "\r\n";
				}

				SimpleDateFormat time = new SimpleDateFormat("yyyy-MM-dd");
				String curTime = time.format(new Date());
				String fileName = "stoneBet/bet_" + curTime;
				MmochatUtil.writeToFile(fileName, info);
			} catch (Exception e) {
				e.printStackTrace();
			}
		} catch (Exception e2) {
			e2.printStackTrace();
		}
		t = System.currentTimeMillis() - t;
		System.out.println("取消石头剪刀布比赛耗时:" + t + "ms");

		// 保存未处理的客服问题
		System.out.println("8、保存未处理完成的客服问题");
		t = System.currentTimeMillis();
		try {
			Object[] kefuMsgArray = kefuMsg.toArray();
			List<MmochatKefuQuestion> kufuMsgList = new ArrayList<MmochatKefuQuestion>();
			for (int i = 0; i < kefuMsgArray.length; i++) {
				MmochatKefuQuestion msg = (MmochatKefuQuestion) kefuMsgArray[i];
				kufuMsgList.add(msg);
			}
			Gson gson = new Gson();
			String question = gson.toJson(kufuMsgList,
					new TypeToken<List<MmochatKefuQuestion>>() {
					}.getType());
			MmochatDao.saveKefuQuestion(question);
		} catch (Exception e) {
			e.printStackTrace();
		}
		t = System.currentTimeMillis() - t;
		System.out.println("耗时:" + t + "ms");

		// 保存在线玩家数据
		System.out.println("9、保存在线玩家数据");
		t = System.currentTimeMillis();

		// 启动20个线程，20个数据库连接，并发保存用户数据(1000个在线用户，正常情况下要25秒左右)
		int total = saveExitPlayerSqlMap.size();
		for (int i = 0; i < 20; i++) {
			try {
				new Thread(new MmochatGmService().new doSql(onlinePlayers, i))
						.start();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		while (true) {
			int rest = saveExitPlayerSqlMap.size();
			if (rest <= 0) {
				System.out.println("已保存" + (total - rest) + "/" + total);
				break;
			}
			System.out.println("已保存" + (total - rest) + "/" + total);
			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		t = System.currentTimeMillis() - t;
		System.out.println("保存玩家数据耗时:" + t + "ms");

		// 保存玩家私聊记录
		System.out.println("10、保存玩家私聊记录");
		try {
			SimpleDateFormat time = new SimpleDateFormat("yyyy-MM-dd");
			String curTime = time.format(new Date());
			String fileName = "chat/chat_" + curTime;
			int index = 0;
			int fIndex = 1;
			String tmp = "";
			for (Entry<String, String> entry : MmochatFriendService.privateChatMap
					.entrySet()) {
				String key = entry.getKey();
				String content = entry.getValue();
				tmp += "[" + key + "]\r\n" + content
						+ "\r\n______________________________________\r\n\r\n";
				if (index > 500) {
					index = 0;
					MmochatUtil.writeToFile(fileName, tmp);
					fIndex++;
					tmp = "";
				}
				index++;
			}
			if (tmp.length() > 0) {
				MmochatUtil.writeToFile(fileName, tmp);
			}
		} catch (Exception e1) {
			e1.printStackTrace();
		}

		// 保存预充值数据
		System.out.println("11、保存预充值数据");
		try {
			if (delayPays != null && delayPays.size() > 0) {
				SimpleDateFormat time = new SimpleDateFormat("yyyy-MM-dd-HH-mm");
				String curTime = time.format(new Date());
				String fileName = "pay/pay_" + curTime;

				Gson gson = new Gson();
				String delayPayData = gson.toJson(delayPays,
						new TypeToken<Map<Integer, MmochatDelayPay>>() {
						}.getType());
				if (delayPayData != null && delayPayData.length() > 0) {
					MmochatUtil.writeToFile(fileName, delayPayData);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		System.out.println("12、退出所有线程池");
		// 关闭所有线程池
		try {
			MmochatBattleService.checkActionTimeOutThread.shutdownNow();
			MmochatBattleService.updateOrdereThread.shutdownNow();
			MmochatClientVerionServer.checkFileThread.shutdownNow();
			checkUnusedPlayerThread.shutdownNow();
			MmochatMainService.checkDeadManThread.shutdownNow();
			MmochatMainService.checkManLeavingGame.shutdownNow();
			MmochatMotionService.es_line.shutdownNow();
			MmochatMotionService.sendMotionThread.shutdownNow();
			MmochatNpcService.rankThread.shutdownNow();
			MmochatNpcService.checkBossLifeThread.shutdownNow();
			MmochatNpcService.createMapBossThread.shutdownNow();
			MmochatPropService.checkPropEffectThread.shutdownNow();
			MmochatPropService.checkFlyMachineThread.shutdownNow();
			MmochatScheduleJobService.es.shutdownNow();
			if (MmochatScheduleJobService.sched != null) {
				MmochatScheduleJobService.sched.shutdown();
			}
			MmochatServerListService.serverListThread.shutdownNow();
			MmochatServerListService.clientVersionThread.shutdownNow();
			if (MmochatStatisticsService.sched != null) {
				MmochatStatisticsService.sched.shutdown();
			}
			Thread.sleep(1000);
		} catch (InterruptedException e) {
		} catch (Exception e) {
		}
		System.out.println("13、调用System.exit(0)");
		System.exit(0);
	}

	class doSql implements Runnable {
		List<MmochatPlayer> playerList = null;
		int start;

		public doSql(List<MmochatPlayer> playerList, int start) {
			this.playerList = playerList;
			this.start = start;
		}

		public void run() {
			try {
				for (int i = start; i < playerList.size(); i += 20) {
					try {
						MmochatPlayer me = playerList.get(i);
						if (me != null) {
							if (!me.isGuest()) {
								boolean success = false;
								for (int s = 0; s < 20; s++) {
									try {
										MmochatDao.updateRoleLeaveGame(me);
										success = true;
										break;
									} catch (Exception e) {
										// 失败，重试
										System.out.println("第" + (start + 1)
												+ "批保存玩家失败，第" + (s + 1)
												+ "次重试!");
										try {
											int wait = 1000 + s * 500;
											Thread.sleep(wait);
										} catch (Exception e1) {
										}
									}
								}
								if (!success) {
									System.out.println("1位玩家保存失败!");
								}
							}
							saveExitPlayerSqlMap.remove(me.getRoleId());
							Thread.sleep(10);
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	// 获取人民币-元宝兑换比率
	public static int getExchangeRate() {
		return MmochatConstant.exchangeRate;
	}

	// 设置人民币-元宝兑换比率
	public static void setExchangeRate(int newRate) {
		MmochatConstant.exchangeRate = newRate;
	}

	// 查询用户日报表数据
	public static List<MmochatDailyUserStatistics> queryDailyUserStatistics(
			String startDate, String endDate) {
		List<MmochatDailyUserStatistics> data = null;

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

		Date start = null, end = null;
		try {
			start = sdf.parse(startDate);
			end = sdf.parse(endDate);
		} catch (ParseException e) {
			return null;
		}
		Timestamp startTime = new Timestamp(start.getTime());
		Timestamp endTime = new Timestamp(end.getTime());
		try {
			data = MmochatDao.queryDailyUserStatistics(startTime, endTime);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return data;
	}

	// 查询收入日报表数据
	public static List<MmochatDailyMoneyStatistics> queryDailyMoneyStatistics(
			String startDate, String endDate) {
		List<MmochatDailyMoneyStatistics> data = null;

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date start = null, end = null;
		try {
			start = sdf.parse(startDate);
			end = sdf.parse(endDate);
		} catch (ParseException e) {
			return null;
		}
		Timestamp startTime = new Timestamp(start.getTime());
		Timestamp endTime = new Timestamp(end.getTime());
		try {
			data = MmochatDao.queryDailyMoneyStatistics(startTime, endTime);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return data;
	}

	// 查询月报表数据
	public static List<MmochatMonthlyStatistics> queryMonthlyStatistics(
			String startDate, String endDate) {
		List<MmochatMonthlyStatistics> data = null;

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date start = null, end = null;
		try {
			start = sdf.parse(startDate);
			end = sdf.parse(endDate);
		} catch (ParseException e) {
			return null;
		}
		Timestamp startTime = new Timestamp(start.getTime());
		Timestamp endTime = new Timestamp(end.getTime());
		try {
			data = MmochatDao.queryMonthlyStatistics(startTime, endTime);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return data;
	}

	// 查询用户在线分布
	public static List<MmochatOnlineInfo> queryOnlineMap(String startDate) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date start = null;
		try {
			start = sdf.parse(startDate);
		} catch (ParseException e) {
			return null;
		}
		Timestamp startTime = new Timestamp(start.getTime());
		Timestamp endTime = new Timestamp(start.getTime()
				+ MmochatConstant.MS_PER_DAY);
		Map<Long, Integer> onlineMap = null;
		try {
			onlineMap = MmochatDao.queryOnlineMap(startTime, endTime);
		} catch (EmptyResultDataAccessException e) {
			return null;
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (onlineMap != null) {
			List<MmochatOnlineInfo> info = new ArrayList<MmochatOnlineInfo>();
			for (Entry<Long, Integer> entry : onlineMap.entrySet()) {
				MmochatOnlineInfo newInfo = new MmochatOnlineInfo();
				newInfo.setOnlineNum(entry.getValue());
				newInfo.setTime(entry.getKey());
				info.add(newInfo);
			}
			Collections.sort(info);
			return info;
		}
		return null;
	}

	// 查询等级分布情况
	public static MmochatRoleLevelInfo getLevelInfo(String startDate) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date start = null;
		try {
			start = sdf.parse(startDate);
		} catch (ParseException e) {
			return null;
		}
		Timestamp startTime = new Timestamp(start.getTime());
		Timestamp endTime = new Timestamp(start.getTime()
				+ MmochatConstant.MS_PER_DAY);
		MmochatRoleLevelInfo levelInfo = null;
		try {
			levelInfo = MmochatDao.queryLevelMap(startTime, endTime);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return levelInfo;
	}

	// 查询指定玩家的交易记录
	public static List<MmochatDealLog> queryRoleDealLog(int roleId,
			String startDate, String endDate) {
		List<MmochatDealLog> data = null;

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date start = null, end = null;
		try {
			start = sdf.parse(startDate);
			end = sdf.parse(endDate);
		} catch (ParseException e) {
			return null;
		}
		Timestamp startTime = new Timestamp(start.getTime());
		Timestamp endTime = new Timestamp(end.getTime());
		try {
			data = MmochatDao.queryRoleDealLog(roleId, startTime, endTime);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return data;
	}

	// 查看指定页的帮派列表(先按等级，再按建设度排序)
	public static List<MmochatGang> getRankGangListByPage(int curPage) {
		List<MmochatGang> gangList = MmochatGangService.getAllGang();
		int showNum = 20;
		int gangNum = gangList.size();
		int pageNum = (int) Math.ceil(1.0 * gangNum
				/ MmochatConstant.maxGangNumShowPerPage);
		curPage = Math.min(curPage, pageNum - 1);
		curPage = Math.max(curPage, 0);
		int showGangNum = Math.min(gangNum - curPage * showNum, showNum);
		if (showGangNum > 0) {
			Collections.sort(gangList, Collections.reverseOrder());
			int baseIndex = curPage * showNum;
			return gangList.subList(baseIndex, baseIndex + showGangNum);
		}
		return null;
	}

	// 根据ID获取帮派
	public static MmochatGang getGangById(int id) {
		MmochatGang gang = MmochatGangService.gangs.get(id);
		if (gang == null) {
			try {
				gang = MmochatDao.getGangByIdIncludeDeleted(id);
			} catch (EmptyResultDataAccessException e) {
			} catch (Exception e) {
				e.printStackTrace();
				return null;
			}
		}
		return gang;
	}

	// 根据名字获取帮派
	public static MmochatGang getGangByName(String gangName) {
		for (MmochatGang gang : MmochatGangService.gangs.values()) {
			if (gang.getName().equals(gangName)) {
				return gang;
			}
		}
		try {
			return MmochatDao.getGangByName(gangName);
		} catch (EmptyResultDataAccessException e) {
			return null;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	// 增加帮派成员贡献值
	public static boolean addGangMemberBuild(int gangId, int roleId, int add) {
		MmochatGang gang = getGangById(gangId);
		if (gang == null) {
			return false;
		}
		MmochatGangMember member = gang.getMembers().get(roleId);
		if (member == null) {
			return false;
		}
		int trueAdd = add;
		if (add < 0) {
			if (gang.getBuildValue() + add < 0) {
				trueAdd = -1 * gang.getBuildValue();
			}
		}
		member.addBuildValue(trueAdd);
		try {
			MmochatDao.updateAfterGangTask(gang, trueAdd, 0);
		} catch (Exception e) {
			e.printStackTrace();
			member.addBuildValue(-1 * trueAdd);
			return false;
		}
		gang.addBuildValue(trueAdd);

		return true;
	}

	// 查询游戏币统计数据
	public static List<MmochatSmallMoneyStatistics> queryLatestSmallMoneyStatistics(
			String startDate, String endDate) {
		List<MmochatSmallMoneyStatistics> data = null;

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date start = null, end = null;
		try {
			start = sdf.parse(startDate);
			end = sdf.parse(endDate);
		} catch (ParseException e) {
			return null;
		}
		Timestamp startTime = new Timestamp(start.getTime());
		Timestamp endTime = new Timestamp(end.getTime());
		try {
			data = MmochatDao.queryLatestSmallMoneyStatistics(startTime,
					endTime);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return data;
	}

	// 查询元宝统计数据
	public static List<MmochatBigMoneyStatistics> queryLatestBigMoneyStatistics(
			String startDate, String endDate) {
		List<MmochatBigMoneyStatistics> data = null;

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date start = null, end = null;
		try {
			start = sdf.parse(startDate);
			end = sdf.parse(endDate);
		} catch (ParseException e) {
			return null;
		}
		Timestamp startTime = new Timestamp(start.getTime());
		Timestamp endTime = new Timestamp(end.getTime());
		try {
			data = MmochatDao.queryLatestBigMoneyStatistics(startTime, endTime);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return data;
	}

	// 删号处理
	public static boolean delRole(int roleId) {
		try {
			MmochatDao.delRole(roleId, true);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		MmochatPlayer me = MmochatMainService.players.get(roleId);
		if (me != null) {
			me.stopDeal();
			MmochatUtil.sendCommonPack(me, new Mmochat_ClientVersionError());
		}
		return true;
	}

	// 封号一定时间
	public static boolean forbiddenRole(int roleId, String endDate,
			String reason) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date end = null;
		try {
			end = sdf.parse(endDate);
		} catch (ParseException e) {
			return false;
		}

		try {
			MmochatDao.forbiddenRole(end.getTime(), roleId);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		MmochatPlayer me = MmochatMainService.getRoleFromBuffer(roleId);
		if (me != null) {
			me.setLock_time_point(end.getTime());
		}
		if (end.getTime() > System.currentTimeMillis()) {
			me = MmochatMainService.players.get(roleId);
			if (me != null) {
				me.stopDeal();
				MmochatUtil
						.sendCommonPack(me, new Mmochat_ClientVersionError());
			}
			if (reason == null) {
				reason = "请联系客服0571-85222407!";
			}
			forbiddenReasons.put(roleId, reason);
		} else {
			forbiddenReasons.remove(roleId);
		}

		return true;
	}

	// 设置哪一天帮战是双倍奖励
	public static void addDoubleAwardDateOfGangBattle(String date) {
		MmochatGangMixedPkGame.addDoubleAwardDate(date);
	}

	// 设置用户完成每月首次充值
	public static void setFirstPayAwardOfThisMonth(int roleId) {
		MmochatPlayer me = MmochatGmService.getRoleInfoById(roleId);
		if (me == null) {
			return;
		}
		if (MmochatConstant.isFirstPayThisMonthActivityOpen) {
			MmochatPropEffect effect = me.getPropEffects().get(
					MmochatPropType.本月首次充值增加全属.getEffectKey());
			if (effect == null) {
				effect = new MmochatPropEffect();
				effect.setPropType(MmochatPropType.本月首次充值增加全属);
				// 效果时间不取道具时间，根据当前时间进行计算，算到本月末
				Calendar date = Calendar.getInstance();
				date.add(Calendar.MONTH, 1);
				date.set(Calendar.DAY_OF_MONTH, 1);
				date.set(Calendar.HOUR_OF_DAY, 0);
				date.set(Calendar.MINUTE, 0);
				date.set(Calendar.SECOND, 0);

				long effectTime = date.getTimeInMillis()
						- System.currentTimeMillis();
				if (effectTime < 0) {
					effectTime = 0;
				}
				effect.setRestAmount(effectTime);
				me.addPropEffect(effect);

				// 保存数据库
				List<Object[]> updateObjs = new ArrayList<Object[]>();
				updateObjs.add(new Object[] { me.getGson_propEffects(),
						me.getRoleId() });
				try {
					MmochatDao.batchUpdateRolePropEffect(updateObjs);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}

	}

	// 设置用户心情：如果内容不为空，则作为骗子记录，并且不允许对方修改心情
	// 如果内容为空，则表示取消骗子记录，并允许对方修改心情
	public static void setChiefRecord(int roleId, String recordInfo) {
		MmochatPlayer me = MmochatGmService.getRoleInfoById(roleId);
		if (me == null) {
			return;
		}
		if (recordInfo == null || recordInfo.length() == 0) {
			// 取消记录
			me.getOtherSystemSetting().put(
					MmochatOtherSystemSettingType.允许编辑心情, true);

			me.setMoodInfo("");
			try {
				MmochatDao.setChiefRecord(me);
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else {
			// 设置行骗记录
			me.getOtherSystemSetting().put(
					MmochatOtherSystemSettingType.允许编辑心情, false);

			me.setMoodInfo(recordInfo);
			try {
				MmochatDao.setChiefRecord(me);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	// 20.1 提交卖号申请
	@SkymobiService
	public SkymobiProtocolMessage handleC_20_1(SkymobiHandler handler,
			Mmochat_20_1C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}
		if (me.getLevel() != 0) {
			return MmochatUtil.msgbox(req.getHallState(),
					"请重新创建一个0级角色，然后在本页面提交售号申请!");
		}
		long interval = System.currentTimeMillis() - me.getCreateTime();
		if (interval > MmochatConstant.MS_PER_DAY) {
			return MmochatUtil.msgbox(req.getHallState(),
					"此角色创建已超过24小时，请重新创建一个0级角色，然后在本页面提交售号申请!");
		}
		CreateEditBoxTLV edit = new CreateEditBoxTLV();
		edit.setTitle("请输入您要出售的角色ID");
		edit.setLeftName("发送");
		edit.setRightName("取消");
		edit.setContentLenMax(20);
		edit.setBoxType(CreateEditBoxTLV.TYPE_MSGBOX);
		edit.setInputType(CreateEditBoxTLV.INPUT_ANY << 4);
		edit.addLeftTLV(new ClearDataTLV());
		edit.addLeftTLV(new AddDataTLV((int) me.getRoleId()));
		edit.addLeftTLV(new AddEditBoxTLV());
		edit.addLeftTLV(new SendDataTLV(MmochatConstant.getClientModuleId(),
				MmochatMain.getModuleInstID(),
				MmochatConstant.MSGCODE_MMOCHAT_C_20_2, null));
		ShowWaitingMsgBoxTLV wait = new ShowWaitingMsgBoxTLV();
		wait.setShowCancel(false);
		edit.addLeftTLV(wait);
		return MmochatUtil.tlvResponse(req.getHallState(), edit);
	}

	// 20.2 上传出售角色ID
	@SkymobiService
	public SkymobiProtocolMessage handleC_20_2(SkymobiHandler handler,
			Mmochat_20_2C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}
		if (me.getLevel() != 0) {
			return MmochatUtil.msgbox(req.getHallState(),
					"请重新创建一个0级角色，然后在本页面提交售号申请!");
		}
		long interval = System.currentTimeMillis() - me.getCreateTime();
		if (interval > MmochatConstant.MS_PER_DAY) {
			return MmochatUtil.msgbox(req.getHallState(),
					"此角色创建已超过24小时，请重新创建一个0级角色，然后在本页面提交售号申请!");
		}

		if (req.getEdit() == null || req.getEdit().length() == 0) {
			return MmochatUtil.msgbox(req.getHallState(), "请输入要出售的角色ID!");
		}

		int sellRoleId = 0;
		try {
			int tmp = Integer.parseInt(req.getEdit(), 16);
			sellRoleId = tmp / 3;
			if (tmp != sellRoleId * 3) {
				return MmochatUtil.msgbox(req.getHallState(),
						"角色ID不正确，请输入正确的角色ID!");
			}
		} catch (NumberFormatException e) {
			return MmochatUtil
					.msgbox(req.getHallState(), "角色ID不正确，请输入正确的角色ID!");
		}

		MmochatPlayer sellRole = getRoleInfoById(sellRoleId);
		if (sellRole == null) {
			return MmochatUtil.msgbox(req.getHallState(), "角色不存在，请检查角色ID是否正确!");
		}
		if (sellRole.isDeleted()) {
			return MmochatUtil.msgbox(req.getHallState(), "角色<"
					+ sellRole.getName() + ">已删除，无法出售!");
		}

		// 判断角色是否为冻结状态
		if (System.currentTimeMillis() < sellRole.getLock_time_point()) {
			return MmochatUtil.msgbox(req.getHallState(), "您要出售的角色<"
					+ sellRole.getName()
					+ ">当前为冻结状态，可能是已经在出售中，或者被客服封号，暂时无法继续出售!");
		}

		// 检查是否设了钱庄密码
		if (sellRole.getStore_pwd() == null
				|| sellRole.getStore_pwd().length() == 0) {
			return MmochatUtil.msgbox(req.getHallState(), "您要出售的角色<"
					+ sellRole.getName() + ">未设置钱庄密码!请先设置钱庄密码，然后再提交售号申请!");
		}
		if (sellRole.getStore_pwd().length() < 19) {
			try {
				Long.parseLong(sellRole.getStore_pwd());
				return MmochatUtil.msgbox(req.getHallState(), "您要出售的角色<"
						+ sellRole.getName() + ">的钱庄密码过于简单，出售角色时钱庄密码"
						+ MmochatUtil.wrapColor("不允许为纯数字", Color.red) + "!"
						+ "请先修改钱庄密码，然后再提交售号申请!");
			} catch (NumberFormatException e) {
			}
		}

		// 生成订单
		MmochatRoleDeal deal = new MmochatRoleDeal();
		deal.setSellerId(me.getRoleId());
		deal.setSellRoleId(sellRole.getRoleId());
		deal.setSellRoleName(sellRole.getName());
		roleDeals.put(deal.getId(), deal);

		// 输入钱庄密码
		CreateEditBoxTLV edit = new CreateEditBoxTLV();
		edit.setTitle("请输入<" + sellRole.getName() + ">的钱庄密码");
		edit.setLeftName("发送");
		edit.setRightName("取消");
		edit.setContentLenMax(20);
		edit.setBoxType(CreateEditBoxTLV.TYPE_MSGBOX);
		edit.setInputType(CreateEditBoxTLV.INPUT_ANY << 4);
		edit.addLeftTLV(new ClearDataTLV());
		edit.addLeftTLV(new AddDataTLV((int) me.getRoleId()));
		edit.addLeftTLV(new AddDataTLV((int) deal.getId()));
		edit.addLeftTLV(new AddEditBoxTLV());
		edit.addLeftTLV(new SendDataTLV(MmochatConstant.getClientModuleId(),
				MmochatMain.getModuleInstID(),
				MmochatConstant.MSGCODE_MMOCHAT_C_20_3, null));
		ShowWaitingMsgBoxTLV wait = new ShowWaitingMsgBoxTLV();
		wait.setShowCancel(false);
		edit.addLeftTLV(wait);
		edit.addRightTLV(new ClearDataTLV());
		edit.addRightTLV(new AddDataTLV((int) me.getRoleId()));
		edit.addRightTLV(new AddDataTLV((int) deal.getId()));
		edit.addRightTLV(new SendDataTLV(MmochatConstant.getClientModuleId(),
				MmochatMain.getModuleInstID(),
				MmochatConstant.MSGCODE_MMOCHAT_C_20_4, null));

		return MmochatUtil.tlvResponse(req.getHallState(), edit);
	}

	// 20.3 上传出售角色的钱庄密码
	@SkymobiService
	public SkymobiProtocolMessage handleC_20_3(SkymobiHandler handler,
			Mmochat_20_3C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			roleDeals.remove(req.getDealId());
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}

		if (req.getEdit() == null || req.getEdit().length() == 0) {
			roleDeals.remove(req.getDealId());
			return MmochatUtil.msgbox(req.getHallState(), "请输入要出售的角色的钱庄密码!");
		}

		MmochatRoleDeal deal = roleDeals.get(req.getDealId());
		if (deal == null || deal.getState() == MmochatRoleDealState.交易关闭) {
			return MmochatUtil.msgbox(req.getHallState(), "本次交易已关闭，请重新申请!");
		}

		MmochatPlayer sellRole = getRoleInfoById(deal.getSellRoleId());
		if (sellRole == null) {
			roleDeals.remove(req.getDealId());
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}

		// 检查钱庄密码
		if (!req.getEdit().equals(sellRole.getStore_pwd())) {
			roleDeals.remove(req.getDealId());
			return MmochatUtil.msgbox(req.getHallState(), "您输入的钱庄密码不正确!请输入正确的<"
					+ sellRole.getName() + ">的钱庄密码!");
		}

		// 验证最近30天交易记录的IMEI
		{
			List<MmochatDealLog> data = null;
			Timestamp startTime = new Timestamp(System.currentTimeMillis() - 30
					* MmochatConstant.MS_PER_DAY);
			Timestamp endTime = new Timestamp(System.currentTimeMillis());
			try {
				data = MmochatDao.queryRoleDealLog(sellRole.getRoleId(),
						startTime, endTime);
			} catch (Exception e) {
				e.printStackTrace();
				roleDeals.remove(req.getDealId());
				return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
			}
			if (data == null || data.size() == 0) {
				roleDeals.remove(req.getDealId());
				return MmochatUtil.msgbox(req.getHallState(), sellRole
						.getName()
						+ "最近30天没有在游戏内进行过交易，无法出售!");
			}
			if (data != null) {
				for (MmochatDealLog dealLog : data) {
					if (dealLog.getRoleId1() == sellRole.getRoleId()) {
						if (!dealLog.getRole1Imei().equals(me.getImei())) {
							roleDeals.remove(req.getDealId());
							// 交易时间到现在的距离
							long costTime = System.currentTimeMillis()
									- dealLog.getTime().getTime();
							long restTime = 30 * MmochatConstant.MS_PER_DAY
									- costTime;
							int day = (int) (restTime / MmochatConstant.MS_PER_DAY);
							int hour = (int) ((restTime - day
									* MmochatConstant.MS_PER_DAY) / MmochatConstant.MS_PER_HOUR);
							String restTimeInfo = "";
							if (day > 0) {
								restTimeInfo += day + "天";
							}
							if (hour > 0) {
								restTimeInfo += hour + "小时";
							} else {
								restTimeInfo += "<1小时";
							}
							return MmochatUtil.msgbox(req.getHallState(),
									"您要出售的角色<"
											+ sellRole.getName()
											+ ">在30天内，"
											+ MmochatUtil.wrapColor(
													"有不同于您当前使用的手机登陆并进行过交易",
													Color.red) + "，"
											+ "暂时无法出售!" + restTimeInfo
											+ "后如果没有其它手机登陆并交易，此号即可出售。");
						}
					} else {
						if (!dealLog.getRole2Imei().equals(me.getImei())) {
							roleDeals.remove(req.getDealId());
							// 交易时间到现在的距离
							long costTime = System.currentTimeMillis()
									- dealLog.getTime().getTime();
							long restTime = 30 * MmochatConstant.MS_PER_DAY
									- costTime;
							int day = (int) (restTime / MmochatConstant.MS_PER_DAY);
							int hour = (int) ((restTime - day
									* MmochatConstant.MS_PER_DAY) / MmochatConstant.MS_PER_HOUR);
							String restTimeInfo = "";
							if (day > 0) {
								restTimeInfo += day + "天";
							}
							if (hour > 0) {
								restTimeInfo += hour + "小时";
							} else {
								restTimeInfo += "<1小时";
							}
							return MmochatUtil.msgbox(req.getHallState(),
									"您要出售的角色<"
											+ sellRole.getName()
											+ ">在30天内，"
											+ MmochatUtil.wrapColor(
													"有不同于您当前使用的手机登陆并进行过交易",
													Color.red) + "，"
											+ "暂时无法出售!" + restTimeInfo
											+ "后如果没有其它手机登陆并交易，此号即可出售。");
						}
					}
				}
			}
		}

		// 输入售价
		CreateEditBoxTLV edit = new CreateEditBoxTLV();
		edit.setTitle("请输入出售价格(单位：元)\n"
				+ MmochatUtil.wrapColor("若价格为0，则角色直接转移到当前冒泡账号下", Color.green));
		edit.setLeftName("输入");
		edit.setRightName("取消");
		edit.setContentLenMax(20);
		edit.setBoxType(CreateEditBoxTLV.TYPE_MSGBOX);
		edit.setInputType(CreateEditBoxTLV.INPUT_NUM << 4);
		edit.addLeftTLV(new ClearDataTLV());
		edit.addLeftTLV(new AddDataTLV((int) me.getRoleId()));
		edit.addLeftTLV(new AddDataTLV((int) deal.getId()));
		edit.addLeftTLV(new AddEditBoxTLV());
		edit.addLeftTLV(new SendDataTLV(MmochatConstant.getClientModuleId(),
				MmochatMain.getModuleInstID(),
				MmochatConstant.MSGCODE_MMOCHAT_C_20_5, null));
		ShowWaitingMsgBoxTLV wait = new ShowWaitingMsgBoxTLV();
		wait.setShowCancel(false);
		edit.addLeftTLV(wait);
		edit.addRightTLV(new ClearDataTLV());
		edit.addRightTLV(new AddDataTLV((int) me.getRoleId()));
		edit.addRightTLV(new AddDataTLV((int) deal.getId()));
		edit.addRightTLV(new SendDataTLV(MmochatConstant.getClientModuleId(),
				MmochatMain.getModuleInstID(),
				MmochatConstant.MSGCODE_MMOCHAT_C_20_4, null));

		return MmochatUtil.tlvResponse(req.getHallState(), edit);
	}

	// 20.5 输入售价
	@SkymobiService
	public SkymobiProtocolMessage handleC_20_5(SkymobiHandler handler,
			Mmochat_20_5C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			roleDeals.remove(req.getDealId());
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}

		if (req.getEdit() == null || req.getEdit().length() == 0) {
			roleDeals.remove(req.getDealId());
			return MmochatUtil.msgbox(req.getHallState(), "请输入出售价格!");
		}

		MmochatRoleDeal deal = roleDeals.get(req.getDealId());
		if (deal == null || deal.getState() == MmochatRoleDealState.交易关闭) {
			return MmochatUtil.msgbox(req.getHallState(), "本次交易已关闭，请重新申请!");
		}

		// 检查出售价格
		int price = 0;
		try {
			price = Integer.parseInt(req.getEdit());
		} catch (NumberFormatException e1) {
			roleDeals.remove(req.getDealId());
			return MmochatUtil.msgbox(req.getHallState(), "只能输入纯数字!");
		}
		if (price < 0) {
			roleDeals.remove(req.getDealId());
			return MmochatUtil.msgbox(req.getHallState(), "只能输入不小于0的数字!");
		}
		deal.setPrice(price);

		MmochatPlayer sellRole = getRoleInfoById(deal.getSellRoleId());
		if (sellRole == null) {
			roleDeals.remove(req.getDealId());
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}

		if (price == 0) {
			// 转号，直接进行
			// 如果sellRole在线，先踢下线
			if (sellRole.getSkyId() == me.getSkyId()) {
				roleDeals.remove(req.getDealId());
				return MmochatUtil.msgbox(req.getHallState(), "角色<"
						+ sellRole.getName() + ">已经在您当前使用的冒泡账号下了，无须转移!");
			}
			deal.setState(MmochatRoleDealState.转号成功);
			if (MmochatMainService.isPlayerOnline(sellRole.getRoleId())) {
				sellRole.stopDeal();
				MmochatUtil.sendCommonPack(sellRole,
						new Mmochat_ClientVersionError());
			}

			// 增加操作日志
			String content = "原SkyId:" + sellRole.getSkyId() + ",新SkyId:"
					+ me.getSkyId();

			// 保存数据库
			try {
				MmochatDao.updateRoleSkyId(me.getSkyId(), sellRole.getRoleId());
			} catch (Exception e1) {
				e1.printStackTrace();
				roleDeals.remove(req.getDealId());
				return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
			}
			sellRole.setSkyId(me.getSkyId());

			try {
				MmochatDao.addGmOptionLog(0, sellRole.getRoleId(), sellRole
						.getName(), 21, "自助转号", content);
			} catch (Exception e) {
			}

			// 通知钱庄密码
			sendKufuPrivateMsg(sellRole.getRoleId(), "您以0元价格购得此号，当前钱庄密码是:"
					+ sellRole.getStore_pwd(), false);

			// 转号完成，订单删除，通知用户
			roleDeals.remove(req.getDealId());
			return MmochatUtil.msgbox(req.getHallState(), "操作成功!您的角色<"
					+ MmochatUtil.wrapColor(sellRole.getName(), Color.green)
					+ ">已经成功转移到您当前的冒泡账号下!");
		} else {
			// 请输入您的手机号码
			CreateEditBoxTLV edit = new CreateEditBoxTLV();
			edit.setTitle("请输入您的手机号码\n"
					+ MmochatUtil.wrapColor("交易成功后，交易金额会以话费形式充值到该手机号码!",
							Color.red));
			edit.setLeftName("输入");
			edit.setRightName("取消");
			edit.setContentLenMax(11);
			edit.setBoxType(CreateEditBoxTLV.TYPE_MSGBOX);
			edit.setInputType(CreateEditBoxTLV.INPUT_NUM << 4);
			edit.addLeftTLV(new ClearDataTLV());
			edit.addLeftTLV(new AddDataTLV((int) me.getRoleId()));
			edit.addLeftTLV(new AddDataTLV((int) deal.getId()));
			edit.addLeftTLV(new AddEditBoxTLV());
			edit.addLeftTLV(new SendDataTLV(
					MmochatConstant.getClientModuleId(), MmochatMain
							.getModuleInstID(),
					MmochatConstant.MSGCODE_MMOCHAT_C_20_6, null));
			ShowWaitingMsgBoxTLV wait = new ShowWaitingMsgBoxTLV();
			wait.setShowCancel(false);
			edit.addLeftTLV(wait);
			edit.addRightTLV(new ClearDataTLV());
			edit.addRightTLV(new AddDataTLV((int) me.getRoleId()));
			edit.addRightTLV(new AddDataTLV((int) deal.getId()));
			edit.addRightTLV(new SendDataTLV(MmochatConstant
					.getClientModuleId(), MmochatMain.getModuleInstID(),
					MmochatConstant.MSGCODE_MMOCHAT_C_20_4, null));

			return MmochatUtil.tlvResponse(req.getHallState(), edit);
		}
	}

	// 20.6 输入手机号码
	@SkymobiService
	public SkymobiProtocolMessage handleC_20_6(SkymobiHandler handler,
			Mmochat_20_6C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			roleDeals.remove(req.getDealId());
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}

		if (req.getEdit() == null || req.getEdit().length() != 11) {
			roleDeals.remove(req.getDealId());
			return MmochatUtil.msgbox(req.getHallState(), "输入的手机号码有误!");
		}

		MmochatRoleDeal deal = roleDeals.get(req.getDealId());
		if (deal == null || deal.getState() == MmochatRoleDealState.交易关闭) {
			return MmochatUtil.msgbox(req.getHallState(), "本次交易已关闭，请重新申请!");
		}

		// 检查号码
		try {
			Long.parseLong(req.getEdit());
		} catch (NumberFormatException e2) {
			roleDeals.remove(req.getDealId());
			return MmochatUtil.msgbox(req.getHallState(), "输入的手机号码有误，只能输入数字!");
		}

		deal.setPhone(req.getEdit());
		MmochatPhoneCardType cardType = deal.getPhoneCardType();
		if (cardType == MmochatPhoneCardType.其它) {
			roleDeals.remove(req.getDealId());
			return MmochatUtil.msgbox(req.getHallState(),
					"暂时只支持移动号码、联通号码!您的手机号码暂时无法支持!");
		}

		// 请输入买家ID
		CreateEditBoxTLV edit = new CreateEditBoxTLV();
		edit.setTitle("请输入买家的角色ID");
		edit.setLeftName("输入");
		edit.setRightName("取消");
		edit.setContentLenMax(20);
		edit.setBoxType(CreateEditBoxTLV.TYPE_MSGBOX);
		edit.setInputType(CreateEditBoxTLV.INPUT_ANY << 4);
		edit.addLeftTLV(new ClearDataTLV());
		edit.addLeftTLV(new AddDataTLV((int) me.getRoleId()));
		edit.addLeftTLV(new AddDataTLV((int) deal.getId()));
		edit.addLeftTLV(new AddEditBoxTLV());
		edit.addLeftTLV(new SendDataTLV(MmochatConstant.getClientModuleId(),
				MmochatMain.getModuleInstID(),
				MmochatConstant.MSGCODE_MMOCHAT_C_20_7, null));
		ShowWaitingMsgBoxTLV wait = new ShowWaitingMsgBoxTLV();
		wait.setShowCancel(false);
		edit.addLeftTLV(wait);
		edit.addRightTLV(new ClearDataTLV());
		edit.addRightTLV(new AddDataTLV((int) me.getRoleId()));
		edit.addRightTLV(new AddDataTLV((int) deal.getId()));
		edit.addRightTLV(new SendDataTLV(MmochatConstant.getClientModuleId(),
				MmochatMain.getModuleInstID(),
				MmochatConstant.MSGCODE_MMOCHAT_C_20_4, null));

		return MmochatUtil.tlvResponse(req.getHallState(), edit);

	}

	// 20.7 输入买家ID
	@SkymobiService
	public SkymobiProtocolMessage handleC_20_7(SkymobiHandler handler,
			Mmochat_20_7C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			roleDeals.remove(req.getDealId());
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}

		if (req.getEdit() == null || req.getEdit().length() == 0) {
			roleDeals.remove(req.getDealId());
			return MmochatUtil.msgbox(req.getHallState(), "请输入正确的买家ID!");
		}

		MmochatRoleDeal deal = roleDeals.get(req.getDealId());
		if (deal == null || deal.getState() == MmochatRoleDealState.交易关闭) {
			return MmochatUtil.msgbox(req.getHallState(), "本次交易已关闭，请重新申请!");
		}

		// 检查买家ID
		int buyerId = 0;
		try {
			int tmp = Integer.parseInt(req.getEdit(), 16);
			buyerId = tmp / 3;
			if (tmp != buyerId * 3) {
				roleDeals.remove(req.getDealId());
				return MmochatUtil.msgbox(req.getHallState(),
						"您输入的买家角色ID不正确，请核对后再发!");
			}
		} catch (NumberFormatException e) {
			roleDeals.remove(req.getDealId());
			return MmochatUtil.msgbox(req.getHallState(),
					"您输入的买家角色ID不正确，请核对后再发!");
		}

		MmochatPlayer buyer = getRoleInfoById(buyerId);
		if (buyer == null) {
			roleDeals.remove(req.getDealId());
			return MmochatUtil.msgbox(req.getHallState(),
					"您输入的买家角色ID不正确，请核对后再发!");
		}
		if (buyer.isDeleted()) {
			roleDeals.remove(req.getDealId());
			return MmochatUtil.msgbox(req.getHallState(), "您输入的买家<"
					+ buyer.getName() + ">已删号，无法交易!");
		}

		MmochatPlayer sellRole = getRoleInfoById(deal.getSellRoleId());
		if (sellRole == null) {
			roleDeals.remove(req.getDealId());
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}

		if (sellRole.getSkyId() == buyer.getSkyId()) {
			roleDeals.remove(req.getDealId());
			return MmochatUtil.msgbox(req.getHallState(), "角色<"
					+ sellRole.getName() + ">已经在买家当前使用的冒泡账号下了，无须出售!");
		}

		deal.setBuyerId(buyerId);
		deal.setBuyerName(buyer.getName());
		deal.setBuyerSkyId(buyer.getSkyId());

		// 核对买家信息
		CreateMsgBoxTLV msgbox = new CreateMsgBoxTLV();
		String msg = "请核实买家信息：\n角色名:"
				+ MmochatUtil.wrapColor(buyer.getName(), Color.green) + "\n等级:"
				+ buyer.getLevelInfo() + "\n如果买家信息正确，请点继续!";
		msgbox.setContent(new Text(msg));
		msgbox.setLeftName("继续");
		msgbox.setRightName("取消");
		msgbox.addLeftTLV(new ClearDataTLV());
		msgbox.addLeftTLV(new AddDataTLV((int) me.getRoleId()));
		msgbox.addLeftTLV(new AddDataTLV((int) deal.getId()));
		msgbox.addLeftTLV(new SendDataTLV(MmochatConstant.getClientModuleId(),
				MmochatMain.getModuleInstID(),
				MmochatConstant.MSGCODE_MMOCHAT_C_20_8, null));

		msgbox.addRightTLV(new ClearDataTLV());
		msgbox.addRightTLV(new AddDataTLV((int) me.getRoleId()));
		msgbox.addRightTLV(new AddDataTLV((int) deal.getId()));
		msgbox.addRightTLV(new SendDataTLV(MmochatConstant.getClientModuleId(),
				MmochatMain.getModuleInstID(),
				MmochatConstant.MSGCODE_MMOCHAT_C_20_4, null));

		return MmochatUtil.tlvResponse(req.getHallState(), msgbox);
	}

	// 20.8确认买家ID
	@SkymobiService
	public SkymobiProtocolMessage handleC_20_8(SkymobiHandler handler,
			Mmochat_20_8C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			roleDeals.remove(req.getDealId());
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}

		MmochatRoleDeal deal = roleDeals.get(req.getDealId());
		if (deal == null || deal.getState() == MmochatRoleDealState.交易关闭) {
			return MmochatUtil.msgbox(req.getHallState(), "本次交易已关闭，请重新申请!");
		}

		MmochatPlayer buyer = getRoleInfoById(deal.getBuyerId());
		if (buyer == null) {
			roleDeals.remove(req.getDealId());
			return MmochatUtil.msgbox(req.getHallState(),
					"您输入的买家角色ID不正确，请核对后再发!");
		}
		if (buyer.isDeleted()) {
			roleDeals.remove(req.getDealId());
			return MmochatUtil.msgbox(req.getHallState(), "您输入的买家<"
					+ buyer.getName() + ">已删号，无法交易!");
		}

		MmochatPlayer sellRole = getRoleInfoById(deal.getSellRoleId());
		if (sellRole == null) {
			roleDeals.remove(req.getDealId());
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}

		if (sellRole.getSkyId() == buyer.getSkyId()) {
			roleDeals.remove(req.getDealId());
			return MmochatUtil.msgbox(req.getHallState(), "角色<"
					+ sellRole.getName() + ">已经在买家当前使用的冒泡账号下了，无须出售!");
		}

		// 踢下线
		if (MmochatMainService.isPlayerOnline(sellRole.getRoleId())) {
			sellRole.stopDeal();
			MmochatUtil.sendCommonPack(sellRole,
					new Mmochat_ClientVersionError());
		}

		// 禁止登陆1小时
		long endTime = System.currentTimeMillis() + MmochatConstant.MS_PER_HOUR;
		try {
			MmochatDao.forbiddenRole(endTime, sellRole.getRoleId());
		} catch (Exception e) {
			e.printStackTrace();
			roleDeals.remove(req.getDealId());
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}
		forbiddenReasons.put(sellRole.getRoleId(),
				"官方角色出售期间，角色会被封冻，在角色出售成功或失败时，角色自动解封!");

		sellRole.setLock_time_point(endTime);

		deal.setNewLifeTimeFromNow(MmochatConstant.MS_PER_HOUR);
		deal.setState(MmochatRoleDealState.等待支付封1小时);

		// 通知买家
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
		String t = sdf.format(new Date(deal.getCreateTime()
				+ deal.getLifeTime()));
		sendKufuPrivateMsg(deal.getBuyerId(), "您有一笔"
				+ MmochatUtil.wrapColor("角色交易订单", Color.green)
				+ "等待处理!\n"
				+ MmochatUtil.wrapColor("请按9键进入<玩家系统>--<官方线下交易>--<我的角色订单>",
						Color.red) + ",查看订单详情并进行处理!\n"
				+ MmochatUtil.wrapColor(t + "之后订单自动取消", Color.green), false);

		// 通知卖家查看订单状态
		return MmochatUtil.msgbox(req.getHallState(), MmochatUtil.wrapColor(
				"出售订单创建成功，系统会联系买家并帮助您完成出售。您可以在"
						+ MmochatUtil.wrapColor("<我的角色订单>", Color.green)
						+ "中查询当前订单处理进度!", Color.yellow));

	}

	// 20.9 查看订单
	@SkymobiService
	public SkymobiProtocolMessage handleC_20_9(SkymobiHandler handler,
			Mmochat_20_9C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}

		MmochatRoleDeal deal = roleDeals.get(req.getDealId());
		if (deal == null) {
			return MmochatUtil.msgbox(req.getHallState(), "本次交易已关闭!");
		}

		if (me.getRoleId() == deal.getSellerId()) {
			// 出售者
			CreateTlvWin tlv = new CreateTlvWin();
			tlv.setWinType(WinType.Text);
			tlv.setRightName("返回");
			tlv.setTitle("我的出售订单");
			tlv.setWinHeight(208);
			tlv.addRightTLV(new CloseWinTLV());
			String content = "";

			switch (deal.getState()) {
			case 等待支付封1小时: {
				tlv.setLeftName("操作");
				ShowPopupMenuTLV menu = new ShowPopupMenuTLV();

				CreateEditBoxTLV edit = new CreateEditBoxTLV();
				edit.setTitle("请输入聊天内容");
				edit.setLeftName("发送");
				edit.setRightName("取消");
				edit.setContentLenMax(255);
				edit.setBoxType(CreateEditBoxTLV.TYPE_MSGBOX);
				edit.setInputType(CreateEditBoxTLV.INPUT_ANY << 4);
				edit.addLeftTLV(new ClearDataTLV());
				edit.addLeftTLV(new AddDataTLV((int) deal.getBuyerId()));
				edit.addLeftTLV(new AddDataTLV((int) me.getRoleId()));
				edit.addLeftTLV(new AddEditBoxTLV());
				edit.addLeftTLV(new SendDataTLV(MmochatConstant
						.getClientModuleId(), MmochatMain.getModuleInstID(),
						MmochatConstant.MSGCODE_MMOCHAT_C_10_4, null));
				menu.addItemEvent("联系买家", edit);

				ShowWaitingMsgBoxTLV wait = new ShowWaitingMsgBoxTLV();
				wait.setShowCancel(false);
				menu.addItemEvent("取消本次交易", new ClearDataTLV(), new AddDataTLV(
						(int) me.getRoleId()), new AddDataTLV((int) deal
						.getId()), new SendDataTLV(MmochatConstant
						.getClientModuleId(), MmochatMain.getModuleInstID(),
						MmochatConstant.MSGCODE_MMOCHAT_C_20_10, null), wait);

				tlv.addLeftTLV(menu);
				content += MmochatUtil.wrapColor("[出售角色]\n", Color.yellow);
				content += deal.getSellRoleName() + "(ID:"
						+ Integer.toHexString(deal.getSellRoleId() * 3)
						+ ")\n\n";
				content += MmochatUtil.wrapColor("[出售价格]\n", Color.yellow);
				content += deal.getPrice() + "元\n\n";
				content += MmochatUtil.wrapColor("[买家信息]\n", Color.yellow);
				content += deal.getBuyerName() + "(ID:"
						+ Integer.toHexString(deal.getBuyerId() * 3) + ")\n\n";
				content += MmochatUtil.wrapColor("[交易进度]\n", Color.yellow);
				content += "等待买家上传手机充值卡信息。"
						+ (deal.getRestTime() / MmochatConstant.MS_PER_MINUTE)
						+ "分钟后订单将超时关闭!\n订单有效期内您出售的角色将被封冻。";
				break;
			}
			case 已支付封5天: {
				content += MmochatUtil.wrapColor("[出售角色]\n", Color.yellow);
				content += deal.getSellRoleName() + "(ID:"
						+ Integer.toHexString(deal.getSellRoleId() * 3)
						+ ")\n\n";
				content += MmochatUtil.wrapColor("[出售价格]\n", Color.yellow);
				content += deal.getPrice() + "元\n\n";
				content += MmochatUtil.wrapColor("[买家信息]\n", Color.yellow);
				content += deal.getBuyerName() + "(ID:"
						+ Integer.toHexString(deal.getBuyerId() * 3) + ")\n\n";
				content += MmochatUtil.wrapColor("[交易进度]\n", Color.yellow);
				content += "买家已上传充值卡信息。请等待客服工作人员为您充值!"
						+ "客服会在周一至周五10:00-18:00期间为您服务，如果60分钟内未完成交易，"
						+ "您可以打客服电话0571-85222407联系客服帮您及时受理!";
				break;
			}
			case 出售成功: {
				content += MmochatUtil.wrapColor("[出售角色]\n", Color.yellow);
				content += deal.getSellRoleName() + "(ID:"
						+ Integer.toHexString(deal.getSellRoleId() * 3)
						+ ")\n\n";
				content += MmochatUtil.wrapColor("[出售价格]\n", Color.yellow);
				content += deal.getPrice() + "元\n\n";
				content += MmochatUtil.wrapColor("[买家信息]\n", Color.yellow);
				content += deal.getBuyerName() + "(ID:"
						+ Integer.toHexString(deal.getBuyerId() * 3) + ")\n\n";
				content += MmochatUtil.wrapColor("[交易进度]\n", Color.yellow);
				content += "交易已成功!相应金额已充值到您手机话费中。如有疑异，"
						+ "请打客服电话0571-85222407联系客服。";
				break;
			}
			case 交易关闭: {
				content += MmochatUtil.wrapColor("[出售角色]\n", Color.yellow);
				content += deal.getSellRoleName() + "(ID:"
						+ Integer.toHexString(deal.getSellRoleId() * 3)
						+ ")\n\n";
				content += MmochatUtil.wrapColor("[出售价格]\n", Color.yellow);
				content += deal.getPrice() + "元\n\n";
				content += MmochatUtil.wrapColor("[买家信息]\n", Color.yellow);
				content += deal.getBuyerName() + "(ID:"
						+ Integer.toHexString(deal.getBuyerId() * 3) + ")\n\n";
				content += MmochatUtil.wrapColor("[交易进度]\n", Color.yellow);
				content += "本次交易已经取消!\n原因:" + deal.getDealReason();
				break;
			}
			default:
				break;
			}
			tlv.setContent(new Text(content));

			return MmochatUtil.tlvResponse(req.getHallState(), tlv);
		} else if (me.getRoleId() == deal.getBuyerId()) {
			// 购买者
			CreateTlvWin tlv = new CreateTlvWin();
			tlv.setWinType(WinType.Text);
			tlv.setRightName("返回");
			tlv.setTitle("我的求购订单");
			tlv.setWinHeight(208);
			tlv.addRightTLV(new CloseWinTLV());
			String content = "";

			switch (deal.getState()) {
			case 等待支付封1小时: {
				tlv.setLeftName("操作");
				ShowPopupMenuTLV menu = new ShowPopupMenuTLV();

				ShowWaitingMsgBoxTLV wait = new ShowWaitingMsgBoxTLV();
				wait.setShowCancel(false);

				menu.addItemEvent("上传充值卡信息", new ClearDataTLV(),
						new AddDataTLV((int) me.getRoleId()), new AddDataTLV(
								(int) deal.getId()), new SendDataTLV(
								MmochatConstant.getClientModuleId(),
								MmochatMain.getModuleInstID(),
								MmochatConstant.MSGCODE_MMOCHAT_C_20_12, null),
						wait);

				CreateEditBoxTLV edit = new CreateEditBoxTLV();
				edit.setTitle("请输入聊天内容");
				edit.setLeftName("发送");
				edit.setRightName("取消");
				edit.setContentLenMax(255);
				edit.setBoxType(CreateEditBoxTLV.TYPE_MSGBOX);
				edit.setInputType(CreateEditBoxTLV.INPUT_ANY << 4);
				edit.addLeftTLV(new ClearDataTLV());
				edit.addLeftTLV(new AddDataTLV((int) deal.getSellerId()));
				edit.addLeftTLV(new AddDataTLV((int) me.getRoleId()));
				edit.addLeftTLV(new AddEditBoxTLV());
				edit.addLeftTLV(new SendDataTLV(MmochatConstant
						.getClientModuleId(), MmochatMain.getModuleInstID(),
						MmochatConstant.MSGCODE_MMOCHAT_C_10_4, null));
				menu.addItemEvent("联系买家", edit);

				menu.addItemEvent("取消本次交易", new ClearDataTLV(), new AddDataTLV(
						(int) me.getRoleId()), new AddDataTLV((int) deal
						.getId()), new SendDataTLV(MmochatConstant
						.getClientModuleId(), MmochatMain.getModuleInstID(),
						MmochatConstant.MSGCODE_MMOCHAT_C_20_10, null), wait);

				tlv.addLeftTLV(menu);

				content += MmochatUtil.wrapColor("[交易进度]\n", Color.yellow);
				content += "等待您上传手机充值卡信息。"
						+ (deal.getRestTime() / MmochatConstant.MS_PER_MINUTE)
						+ "分钟后订单将超时关闭\n"
						+ MmochatUtil.wrapColor("请按<操作>-<上传充值卡信息>\n\n",
								Color.red);

				content += MmochatUtil.wrapColor("[购买价格]\n", Color.yellow);
				content += deal.getPrice() + "元"
						+ deal.getPhoneCardType().toString() + "\n\n";

				MmochatPlayer sellRole = getRoleInfoById(deal.getSellRoleId());
				content += MmochatUtil.wrapColor("[购买角色信息]\n", Color.yellow);
				if (sellRole == null) {
					content += "角色信息读取失败，请稍候再试!";
				} else {
					content += MmochatPlayerService.getUserAttrInfo(sellRole);
					content += MmochatUtil.wrapColor("金钱:", Color.green)
							+ (sellRole.getSmall_money() + sellRole
									.getStoredSmall_money()) + "\n";
					content += MmochatUtil.wrapColor("宠物:", Color.green);
					String petInfo = "";
					for (MmochatPet pet : sellRole.getPets().values()) {
						if (pet.getPetType() == MmochatPetType.野生
								|| pet.getPetType() == MmochatPetType.药兽
								|| pet.getBorrowFromRoleId() != null) {
							continue;
						}
						petInfo += pet.getLevelInfo()
								+ pet.getRoleType().toString() + "("
								+ pet.getPetType().toString() + ")\n";
					}
					for (MmochatPet pet : sellRole.getStoredPets().values()) {
						if (pet.getPetType() == MmochatPetType.野生
								|| pet.getPetType() == MmochatPetType.药兽
								|| pet.getBorrowFromRoleId() != null) {
							continue;
						}
						petInfo += pet.getLevelInfo()
								+ pet.getRoleType().toString() + "("
								+ pet.getPetType().toString() + ")\n";
					}
					if (petInfo.length() == 0) {
						content += "无";
					} else {
						content += petInfo;
					}
				}
				break;
			}
			case 已支付封5天: {
				tlv.setLeftName("操作");
				ShowPopupMenuTLV menu = new ShowPopupMenuTLV();

				ShowWaitingMsgBoxTLV wait = new ShowWaitingMsgBoxTLV();
				wait.setShowCancel(false);

				menu.addItemEvent("补充上传充值卡", new ClearDataTLV(),
						new AddDataTLV((int) me.getRoleId()), new AddDataTLV(
								(int) deal.getId()), new SendDataTLV(
								MmochatConstant.getClientModuleId(),
								MmochatMain.getModuleInstID(),
								MmochatConstant.MSGCODE_MMOCHAT_C_20_12, null),
						wait);

				CreateEditBoxTLV edit = new CreateEditBoxTLV();
				edit.setTitle("请输入聊天内容");
				edit.setLeftName("发送");
				edit.setRightName("取消");
				edit.setContentLenMax(255);
				edit.setBoxType(CreateEditBoxTLV.TYPE_MSGBOX);
				edit.setInputType(CreateEditBoxTLV.INPUT_ANY << 4);
				edit.addLeftTLV(new ClearDataTLV());
				edit.addLeftTLV(new AddDataTLV((int) deal.getSellerId()));
				edit.addLeftTLV(new AddDataTLV((int) me.getRoleId()));
				edit.addLeftTLV(new AddEditBoxTLV());
				edit.addLeftTLV(new SendDataTLV(MmochatConstant
						.getClientModuleId(), MmochatMain.getModuleInstID(),
						MmochatConstant.MSGCODE_MMOCHAT_C_10_4, null));
				menu.addItemEvent("联系买家", edit);

				tlv.addLeftTLV(menu);

				deal.clearInvalidPhoneCard();
				content += MmochatUtil.wrapColor("[交易进度]\n", Color.yellow);
				content += "您已上传" + deal.getPhoneCards().size()
						+ "张充值卡，请等待客服工作人员为卖家充值并转移角色，"
						+ "如果您需继续上传更多的充值卡，请按<操作>键继续上传。\n"
						+ "客服会在周一至周五10:00-18:00期间为您服务，如果60分钟内未完成交易，"
						+ "您可以打客服电话0571-85222407联系客服帮您及时受理!\n\n";

				MmochatPlayer sellRole = getRoleInfoById(deal.getSellRoleId());
				content += MmochatUtil.wrapColor("[购买角色信息]\n", Color.yellow);
				if (sellRole == null) {
					content += "角色信息读取失败，请稍候再试!";
				} else {
					content += MmochatPlayerService.getUserAttrInfo(sellRole);
				}
				break;
			}
			case 出售成功: {
				content += MmochatUtil.wrapColor("[交易进度]\n", Color.yellow);
				content += "交易已成功!角色已转到您当前冒泡账号下，请退出查收!如有疑异，"
						+ "请打客服电话0571-85222407联系客服。\n\n";

				content += MmochatUtil.wrapColor("[购买角色]\n", Color.yellow);
				content += deal.getSellRoleName() + "(ID:"
						+ Integer.toHexString(deal.getSellRoleId() * 3)
						+ ")\n\n";
				content += MmochatUtil.wrapColor("[购买价格]\n", Color.yellow);
				content += deal.getPrice() + "元\n\n";
				content += MmochatUtil.wrapColor("[卖家信息]\n", Color.yellow);
				content += deal.getSellRoleName() + "(ID:"
						+ Integer.toHexString(deal.getSellerId() * 3) + ")";

				break;
			}
			case 交易关闭: {
				content += MmochatUtil.wrapColor("[交易进度]\n", Color.yellow);
				content += "本次交易已经取消!\n原因:" + deal.getDealReason() + "\n\n";
				content += MmochatUtil.wrapColor("[购买角色]\n", Color.yellow);
				content += deal.getSellRoleName() + "(ID:"
						+ Integer.toHexString(deal.getSellRoleId() * 3)
						+ ")\n\n";
				content += MmochatUtil.wrapColor("[购买价格]\n", Color.yellow);
				content += deal.getPrice() + "元\n\n";
				content += MmochatUtil.wrapColor("[卖家信息]\n", Color.yellow);
				content += deal.getSellRoleName() + "(ID:"
						+ Integer.toHexString(deal.getSellerId() * 3) + ")";

				break;
			}
			default:
				break;
			}
			tlv.setContent(new Text(content));

			return MmochatUtil.tlvResponse(req.getHallState(), tlv);

		} else {
			return MmochatUtil.msgbox(req.getHallState(), "这不是您的订单!");
		}
	}

	// 20.10 取消订单
	@SkymobiService
	public SkymobiProtocolMessage handleC_20_10(SkymobiHandler handler,
			Mmochat_20_10C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}

		MmochatRoleDeal deal = roleDeals.get(req.getDealId());
		if (deal == null || deal.getState() == MmochatRoleDealState.交易关闭) {
			return MmochatUtil.msgbox(req.getHallState(), "本次交易已关闭!");
		}

		CreateMsgBoxTLV msgbox = new CreateMsgBoxTLV();
		msgbox.setContent(new Text("您确定要放弃本次交易么?"));
		msgbox.setLeftName("放弃");
		msgbox.setRightName("取消");
		msgbox.addLeftTLV(new ClearDataTLV());
		msgbox.addLeftTLV(new AddDataTLV((int) me.getRoleId()));
		msgbox
				.addLeftTLV(new SendDataTLV(
						MmochatConstant.getClientModuleId(), MmochatMain
								.getModuleInstID(),
						MmochatConstant.MSGCODE_MMOCHAT_C_20_11, (int) req
								.getDealId()));
		return MmochatUtil.tlvResponse(req.getHallState(), msgbox);

	}

	// 20.11确认 取消订单
	@SkymobiService
	public SkymobiProtocolMessage handleC_20_11(SkymobiHandler handler,
			Mmochat_20_11C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}

		MmochatRoleDeal deal = roleDeals.get(req.getDealId());
		if (deal == null || deal.getState() == MmochatRoleDealState.交易关闭) {
			return MmochatUtil.msgbox(req.getHallState(), "本次交易已关闭!");
		}

		if (deal.getState() != MmochatRoleDealState.等待支付封1小时) {
			return MmochatUtil.msgbox(req.getHallState(), "当前无法取消交易，请刷新交易信息!");
		}
		synchronized (deal) {
			if (deal.getState() != MmochatRoleDealState.等待支付封1小时) {
				return MmochatUtil.msgbox(req.getHallState(),
						"当前无法取消交易，请刷新交易信息!");
			} else {
				deal.setState(MmochatRoleDealState.交易关闭);
				deal.setNewLifeTimeFromNow(MmochatConstant.MS_PER_DAY * 2);
			}
		}
		if (me.getRoleId() == deal.getSellerId()) {
			deal.setDealReason("卖家取消了本次交易!");
			// 通知买家
			sendKufuPrivateMsg(deal.getBuyerId(), "卖家已经取消了角色<"
					+ deal.getSellRoleName() + ">的交易!", false);
		} else if (me.getRoleId() == deal.getBuyerId()) {
			deal.setDealReason("买家取消了本次交易!");
			// 通知卖家
			sendKufuPrivateMsg(deal.getSellerId(), "买家已经取消了角色<"
					+ deal.getSellRoleName() + ">的交易!", false);
		}

		// 角色解冻
		MmochatPlayer sellRole = getRoleInfoById(deal.getSellRoleId());
		long endTime = System.currentTimeMillis();
		try {
			MmochatDao.forbiddenRole(endTime, sellRole.getRoleId());
		} catch (Exception e) {
			e.printStackTrace();
		}
		sellRole.setLock_time_point(endTime);
		forbiddenReasons.remove(sellRole.getRoleId());

		return MmochatUtil.msgbox(req.getHallState(), "交易已取消，请刷新交易信息!");

	}

	// 20.12 上传充值卡
	@SkymobiService
	public SkymobiProtocolMessage handleC_20_12(SkymobiHandler handler,
			Mmochat_20_12C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}

		MmochatRoleDeal deal = roleDeals.get(req.getDealId());
		if (deal == null || deal.getState() == MmochatRoleDealState.交易关闭) {
			return MmochatUtil.msgbox(req.getHallState(), "本次交易已关闭!");
		}
		deal.clearInvalidPhoneCard();
		int curNum = deal.getPhoneCards().size();
		String msg = "";
		if (curNum == 0) {
			msg += "请输入"
					+ MmochatUtil.wrapColor(deal.getPhoneCardType().toString(),
							Color.green) + "的卡号("
					+ deal.getPhoneCardType().getAccountLength() + "位数字)";
		} else {
			msg += "您已上传"
					+ curNum
					+ "张充值卡信息!\n如果您需要继续上传，请输入另一张"
					+ MmochatUtil.wrapColor(deal.getPhoneCardType().toString(),
							Color.green) + "的卡号("
					+ deal.getPhoneCardType().getAccountLength() + "位数字)";
		}

		ShowWaitingMsgBoxTLV wait = new ShowWaitingMsgBoxTLV();
		wait.setShowCancel(false);
		CreateEditBoxTLV edit = new CreateEditBoxTLV();
		edit.setTitle(msg);
		edit.setLeftName("上传");
		edit.setRightName("取消");
		edit.setContentLenMax(deal.getPhoneCardType().getAccountLength());
		edit.setBoxType(CreateEditBoxTLV.TYPE_MSGBOX);
		edit.setInputType(CreateEditBoxTLV.INPUT_NUM << 4);
		edit.addLeftTLV(new ClearDataTLV());
		edit.addLeftTLV(new AddDataTLV((int) me.getRoleId()));
		edit.addLeftTLV(new AddDataTLV((int) deal.getId()));
		edit.addLeftTLV(new AddEditBoxTLV());
		edit.addLeftTLV(new SendDataTLV(MmochatConstant.getClientModuleId(),
				MmochatMain.getModuleInstID(),
				MmochatConstant.MSGCODE_MMOCHAT_C_20_13, null));
		edit.addLeftTLV(wait);
		return MmochatUtil.tlvResponse(req.getHallState(), edit);

	}

	// 20.13 上传充值卡的卡号
	@SkymobiService
	public SkymobiProtocolMessage handleC_20_13(SkymobiHandler handler,
			Mmochat_20_13C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}

		MmochatRoleDeal deal = roleDeals.get(req.getDealId());
		if (deal == null || deal.getState() == MmochatRoleDealState.交易关闭) {
			return MmochatUtil.msgbox(req.getHallState(), "本次交易已关闭!");
		}

		// 检查卡号
		MmochatPhoneCardType cardType = deal.getPhoneCardType();
		String account = req.getEdit();
		if (account.length() != cardType.getAccountLength()) {
			return MmochatUtil.msgbox(req.getHallState(), "卡号错误，卡号长度应该为"
					+ cardType.getAccountLength() + "位!请确认您提供的是"
					+ MmochatUtil.wrapColor(cardType.toString(), Color.magenta)
					+ "(由卖家手机号类型决定)!");
		}

		// 增加新卡
		deal.clearInvalidPhoneCard();
		MmochatPhoneCard newCard = new MmochatPhoneCard();
		newCard.setType(cardType);
		newCard.setAccount(account);
		deal.getPhoneCards().put(newCard.getId(), newCard);

		String msg = "请输入卡号为" + account + "的充值卡对应的密码("
				+ cardType.getPasswordLength() + "位)";

		ShowWaitingMsgBoxTLV wait = new ShowWaitingMsgBoxTLV();
		wait.setShowCancel(false);
		CreateEditBoxTLV edit = new CreateEditBoxTLV();
		edit.setTitle(msg);
		edit.setLeftName("上传");
		edit.setRightName("取消");
		edit.setContentLenMax(deal.getPhoneCardType().getPasswordLength());
		edit.setBoxType(CreateEditBoxTLV.TYPE_MSGBOX);
		edit.setInputType(CreateEditBoxTLV.INPUT_NUM << 4);
		edit.addLeftTLV(new ClearDataTLV());
		edit.addLeftTLV(new AddDataTLV((int) me.getRoleId()));
		edit.addLeftTLV(new AddDataTLV((int) deal.getId()));
		edit.addLeftTLV(new AddDataTLV((int) newCard.getId()));
		edit.addLeftTLV(new AddEditBoxTLV());
		edit.addLeftTLV(new SendDataTLV(MmochatConstant.getClientModuleId(),
				MmochatMain.getModuleInstID(),
				MmochatConstant.MSGCODE_MMOCHAT_C_20_14, null));
		edit.addLeftTLV(wait);
		return MmochatUtil.tlvResponse(req.getHallState(), edit);

	}

	// 20.14 上传充值卡的密码
	@SkymobiService
	public SkymobiProtocolMessage handleC_20_14(SkymobiHandler handler,
			Mmochat_20_14C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}

		MmochatRoleDeal deal = roleDeals.get(req.getDealId());
		if (deal == null || deal.getState() == MmochatRoleDealState.交易关闭) {
			return MmochatUtil.msgbox(req.getHallState(), "本次交易已关闭!");
		}

		// 检查密码
		MmochatPhoneCardType cardType = deal.getPhoneCardType();
		String password = req.getEdit();
		if (password.length() != cardType.getPasswordLength()) {
			return MmochatUtil.msgbox(req.getHallState(), "密码错误，密码长度应该为"
					+ cardType.getPasswordLength() + "位!请确认您提供的是"
					+ MmochatUtil.wrapColor(cardType.toString(), Color.magenta)
					+ "(由卖家手机号类型决定)!");
		}

		// 设置卡的密码
		MmochatPhoneCard myCard = deal.getPhoneCards().get(req.getCardId());
		if (myCard == null) {
			return MmochatUtil.msgbox(req.getHallState(), "卡号不存在，请重新输入!");
		}
		myCard.setPassword(password);

		// 继续上传
		deal.clearInvalidPhoneCard();
		int curNum = deal.getPhoneCards().size();
		String msg = "";
		msg += "您已上传"
				+ curNum
				+ "张充值卡信息!\n若需要继续上传，请输入另一张"
				+ MmochatUtil.wrapColor(deal.getPhoneCardType().toString(),
						Color.green) + "的卡号!\n若上传完毕，请按<取消>键!";

		ShowWaitingMsgBoxTLV wait = new ShowWaitingMsgBoxTLV();
		wait.setShowCancel(false);
		CreateEditBoxTLV edit = new CreateEditBoxTLV();
		edit.setTitle(msg);
		edit.setLeftName("确定");
		edit.setRightName("取消");
		edit.setContentLenMax(deal.getPhoneCardType().getAccountLength());
		edit.setBoxType(CreateEditBoxTLV.TYPE_MSGBOX);
		edit.setInputType(CreateEditBoxTLV.INPUT_NUM << 4);
		edit.addLeftTLV(new ClearDataTLV());
		edit.addLeftTLV(new AddDataTLV((int) me.getRoleId()));
		edit.addLeftTLV(new AddDataTLV((int) deal.getId()));
		edit.addLeftTLV(new AddEditBoxTLV());
		edit.addLeftTLV(new SendDataTLV(MmochatConstant.getClientModuleId(),
				MmochatMain.getModuleInstID(),
				MmochatConstant.MSGCODE_MMOCHAT_C_20_13, null));
		edit.addLeftTLV(wait);
		edit.addRightTLV(new ClearDataTLV());
		edit.addRightTLV(new AddDataTLV((int) me.getRoleId()));
		edit.addRightTLV(new AddDataTLV((int) deal.getId()));
		edit.addRightTLV(new SendDataTLV(MmochatConstant.getClientModuleId(),
				MmochatMain.getModuleInstID(),
				MmochatConstant.MSGCODE_MMOCHAT_C_20_15, null));

		return MmochatUtil.tlvResponse(req.getHallState(), edit);

	}

	// 20.15 上传充值卡完成
	@SuppressWarnings("deprecation")
	@SkymobiService
	public SkymobiProtocolMessage handleC_20_15(SkymobiHandler handler,
			Mmochat_20_15C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}

		MmochatRoleDeal deal = roleDeals.get(req.getDealId());
		if (deal == null || deal.getState() == MmochatRoleDealState.交易关闭) {
			return MmochatUtil.msgbox(req.getHallState(), "本次交易已关闭!");
		}

		deal.clearInvalidPhoneCard();
		int curNum = deal.getPhoneCards().size();
		if (curNum == 0) {
			return MmochatUtil
					.msgbox(req.getHallState(), "您还没有上传过正确的充值卡，请先上传!");
		}

		if (deal.getState() == MmochatRoleDealState.等待支付封1小时) {
			synchronized (deal) {
				if (deal.getState() == MmochatRoleDealState.交易关闭) {
					return MmochatUtil.msgbox(req.getHallState(), "本次交易已关闭!");
				}
				deal.setState(MmochatRoleDealState.已支付封5天);
			}
			deal.setNewLifeTimeFromNow(MmochatConstant.MS_PER_DAY * 5);

			// 禁止登陆5天
			MmochatPlayer sellRole = getRoleInfoById(deal.getSellRoleId());
			long endTime = System.currentTimeMillis()
					+ MmochatConstant.MS_PER_DAY * 5;
			try {
				MmochatDao.forbiddenRole(endTime, sellRole.getRoleId());
			} catch (Exception e) {
				e.printStackTrace();
			}
			sellRole.setLock_time_point(endTime);
			forbiddenReasons.put(sellRole.getRoleId(),
					"官方角色出售期间，角色会被封冻，在角色出售成功或失败时，角色自动解封!");

			Date now = new Date();
			int weekday = now.getDay();// 0 = Sunday, 1 = Monday, 2 = Tuesday, 3
			// = Wednesday, 4 = Thursday, 5 =
			// Friday, 6 = Saturday
			int hour = now.getHours();// 0-23

			String info = "请等待客服受理，如果60分钟内未完成交易，请联系客服0571-85222407及时受理!";
			if (weekday == 6 || weekday == 0 || hour < 10 || hour > 17) {
				info = "后续流程由客服受理，受理时间：周一至周五,10:00-18:00。现在不是受理时间，客服会在值班后开始受理您的订单!";
			}

			// 通知卖家
			sendKufuPrivateMsg(deal.getSellerId(), MmochatUtil.wrapColor(me
					.getName(), Color.green)
					+ "已经上传充值卡信息给客服!\n" + info, false);

			return MmochatUtil.msgbox(req.getHallState(), "上传完成!\n" + info);
		} else {
			return MmochatUtil.msgbox(req.getHallState(), "新的充值卡信息已经上传完成!");
		}
	}

	// 关闭标准回答面板
	@SkymobiService
	public SkymobiProtocolMessage handleC_20_18(SkymobiHandler handler,
			Mmochat_20_18C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}

		long questionId = req.getMyQuestionId();
		MmochatKefuQuestion curQuestion = null;
		for (MmochatKefuQuestion question : kefuMsg) {
			if (question.getId() == questionId) {
				curQuestion = question;
				break;
			}
		}
		if (curQuestion == null) {
			// 问题已经完结
			return null;
		}
		return MmochatUtil
				.msgbox(req.getHallState(), "您的问题我们已经记录，稍后客服会进行人工解答!");
	}

	public static String dealRoleOrder(int orderId, boolean success,
			String reason) {
		MmochatRoleDeal deal = roleDeals.get(orderId);
		if (deal == null) {
			return "设置失败!交易不存在!";
		}
		if (deal.getState() != MmochatRoleDealState.已支付封5天) {
			return "设置失败!当前订单状态为:" + deal.getState().getInfo();
		}
		if (success) {
			// 交易成功：设置订单状态，角色解冻，转移角色，修改钱庄密码并下发通知钱庄密码，通知双方交易成功
			MmochatPlayer sellRole = getRoleInfoById(deal.getSellRoleId());

			// 转移角色
			try {
				MmochatDao.updateRoleSkyId(deal.getBuyerSkyId(), sellRole
						.getRoleId());
			} catch (Exception e1) {
				e1.printStackTrace();
				return "数据库繁忙，操作失败!请稍候再试!";
			}

			deal.setState(MmochatRoleDealState.出售成功);
			deal.setDealReason(reason);

			// 角色解冻
			long endTime = System.currentTimeMillis();
			try {
				MmochatDao.forbiddenRole(endTime, sellRole.getRoleId());
			} catch (Exception e) {
				e.printStackTrace();
			}
			sellRole.setLock_time_point(endTime);
			forbiddenReasons.remove(sellRole.getRoleId());

			// 增加操作日志
			String content = "原SkyId:" + sellRole.getSkyId() + ",新SkyId:"
					+ deal.getBuyerSkyId() + "<br/>";
			content += "售价:" + deal.getPrice() + "<br/>";
			content += "卖家手机号:" + deal.getPhone();
			for (MmochatPhoneCard c : deal.getPhoneCards().values()) {
				content += "<br/>卡号:" + c.getAccount() + ",密码:"
						+ c.getPassword();
			}
			sellRole.setSkyId(deal.getBuyerSkyId());

			try {
				MmochatDao.addGmOptionLog(0, sellRole.getRoleId(), sellRole
						.getName(), 21, "出售角色", content);
			} catch (Exception e) {
			}

			// 修改并通知钱庄密码
			int rand = MmochatUtil.getRandomValue(123456, 987654);
			String pwd = rand + "";
			try {
				MmochatDao.updateStorePwd(pwd, MmochatStorePwdState.已设置钱庄密码
						.getValue(), 0, sellRole.getRoleId());
				sellRole.setStore_pwd_state(MmochatStorePwdState.已设置钱庄密码);
				sellRole.setStore_pwd(pwd);
				sellRole.setHasCheckStorePwd(false);
			} catch (Exception e) {
				e.printStackTrace();
			}

			sendKufuPrivateMsg(sellRole.getRoleId(), "恭喜您成功购得此号，当前钱庄密码是:"
					+ sellRole.getStore_pwd() + "，请及时修改钱庄密码!", false);

			// 转号完成，订单删除，通知用户
			roleDeals.remove(orderId);

			// 通知双方交易成功
			sendKufuPrivateMsg(deal.getSellerId(), "恭喜您成功售出<"
					+ sellRole.getName() + ">，相应金额已充值到您手机话费!", false);
			sendKufuPrivateMsg(deal.getBuyerId(), "恭喜您成功购得<"
					+ sellRole.getName() + ">，角色已转移到您当前冒泡账号下!", false);
			return "处理成功，此交易已经成功!";
		} else {
			// 交易失败：设置订单状态，角色解冻，通知双方交易成功
			MmochatPlayer sellRole = getRoleInfoById(deal.getSellRoleId());

			deal.setState(MmochatRoleDealState.交易关闭);
			deal.setDealReason(reason);

			// 角色解冻
			long endTime = System.currentTimeMillis();
			try {
				MmochatDao.forbiddenRole(endTime, sellRole.getRoleId());
			} catch (Exception e) {
				e.printStackTrace();
			}
			sellRole.setLock_time_point(endTime);
			forbiddenReasons.remove(sellRole.getRoleId());

			// 通知双方交易成功
			sendKufuPrivateMsg(deal.getSellerId(), "您要出售的<"
					+ sellRole.getName() + ">，交易已经失败，请查看您的角色订单，了解原因!", false);
			sendKufuPrivateMsg(deal.getBuyerId(), "您要购买的<" + sellRole.getName()
					+ ">，交易已经失败，请查看您的角色订单，了解原因!", false);
			return "处理成功，此交易已经关闭!";

		}
	}

	// 读取历史私聊记录(startDate后的私聊记录)
	public static String getHistoryPrivateChat(String startDate, int roleId1,
			int roleId2) {
		// 查看指定文件夹下所有文件，如果修改时间在startDate之后，则进行加载读取
		Date start = null;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		try {
			start = sdf.parse(startDate);
		} catch (ParseException e) {
			return "日期不正确，格式为：年-月-日";
		}
		long startTick = start.getTime();

		String chatKey;
		if (roleId1 > roleId2) {
			chatKey = roleId1 + "+" + roleId2;
		} else {
			chatKey = roleId2 + "+" + roleId1;
		}
		String startTag = "[" + chatKey + "]";
		String endTag = "\r\n\r\n[";

		File root = new File("chat");
		File[] files = root.listFiles();
		List<MmochatHistoryChat> chats = new ArrayList<MmochatHistoryChat>();
		if (files != null) {
			for (File file : files) {
				if (!file.isFile()) {
					continue;
				}
				if (file.lastModified() > startTick) {
					String content = MmochatUtil.readFile(file);
					if (content != null) {
						int startIndex = content.indexOf(startTag);
						if (startIndex != -1) {
							int endIndex = content.indexOf(endTag,
									startIndex + 1);
							if (endIndex == -1) {
								endIndex = content.length();
							}
							String chat1 = content.substring(startIndex,
									endIndex);
							MmochatHistoryChat c = new MmochatHistoryChat();
							c.setChat(chat1);
							c.setChatTime(file.lastModified());
							chats.add(c);
						}
					}
				}
			}
		}
		Collections.sort(chats);
		String msg = "";
		for (MmochatHistoryChat c : chats) {
			msg += c.getChat() + "<br/>";
		}

		return msg;
	}

	// 按日期读取用户私聊记录(包括内存中和文件中的私聊记录)
	public static String getPrivateChat(String startDate, int roleId1,
			int roleId2) {
		String chatKey;
		if (roleId1 > roleId2) {
			chatKey = roleId1 + "+" + roleId2;
		} else {
			chatKey = roleId2 + "+" + roleId1;
		}
		String chatMsg = MmochatFriendService.privateChatMap.get(chatKey);
		if (chatMsg == null) {
			chatMsg = "";
		}

		String historyMsg = getHistoryPrivateChat(startDate, roleId1, roleId2);
		if (historyMsg == null) {
			historyMsg = "";
		}

		return historyMsg + chatMsg;
	}

	// 预充值功能
	@SkymobiService
	public SkymobiProtocolMessage handleC_20_19(SkymobiHandler handler,
			Mmochat_20_19C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}
		switch (req.getIndex()) {
		case 1: {
			// 预充值活动说明
			CreateTlvWin tlv = new CreateTlvWin();
			tlv.setWinType(WinType.Text);
			tlv.setRightName("返回");
			tlv.setTitle("预充值活动说明");
			tlv.setWinHeight(208);
			tlv.addRightTLV(new CloseWinTLV());
			String content = "";
			content += MmochatUtil.wrapColor("[简介]\n", Color.yellow);
			content += "预充值后，元宝不是马上到账，"
					+ MmochatUtil.wrapColor("一般在1至12小时内到账。", Color.magenta)
					+ "\n\n";
			content += MmochatUtil.wrapColor("[兑换比例]\n", Color.yellow);
			content += MmochatUtil.wrapColor("1元="
					+ MmochatConstant.delayPayMinExchangeRate + "至"
					+ MmochatConstant.delayPayMaxExchangeRate + "元宝随机",
					Color.red)
					+ "\n即1元可兑换最少"
					+ MmochatConstant.delayPayMinExchangeRate
					+ "元宝，最大"
					+ MmochatConstant.delayPayMaxExchangeRate
					+ "元宝。由于预充值的元宝为延后到账，所以兑换比例会有一定优惠，兑换比例"
					+ "每期活动可能都不一样，以本说明为准。\n"
					+ "充值抽奖机会数=获得元宝数/"
					+ MmochatConstant.payValuePerAward
					+ "，本活动无推荐人积分奖励，也不与其它充值活动叠加。\n\n";

			content += MmochatUtil.wrapColor("[活动时间]\n", Color.yellow);
			content += "本活动" + MmochatUtil.wrapColor("不定时开启", Color.green)
					+ "，各区服此活动开启时间不相同。开启后不作特别通知，只有经常关注充值页面才能不错过本活动!\n\n";

			content += MmochatUtil.wrapColor("[参与条件]\n", Color.yellow);
			content += "30级以上用户可以参加。";

			tlv.setContent(new Text(content));
			return MmochatUtil.tlvResponse(req.getHallState(), tlv);
		}
		case 2:
		case 3: {
			// 移动充值卡
			MmochatDelayPay pay = new MmochatDelayPay();
			pay.setRoleId(me.getRoleId());
			if (req.getIndex() == 2) {
				pay.setType(MmochatPhoneCardType.移动充值卡);
			} else if (req.getIndex() == 3) {
				pay.setType(MmochatPhoneCardType.联通充值卡);
			}
			delayPays.put(pay.getId(), pay);

			// 充值卡面额
			CreateTlvWin tlv = new CreateTlvWin();
			tlv.setWinType(WinType.List);
			tlv.setWinId(MmochatConstant.TLV_WIN_DELAYPAY);
			tlv.setLeftName("选择");
			tlv.setRightName("返回");
			tlv.setTitle("请选择充值卡面额");
			tlv.setWinHeight(208);

			ShowWaitingMsgBoxTLV wait = new ShowWaitingMsgBoxTLV();
			wait.setShowCancel(false);
			tlv.addItemEvent("30元" + pay.getType().toString(),
					new ClearDataTLV(), new AddDataTLV((int) 30),
					new AddDataTLV((int) pay.getId()), new SendDataTLV(
							MmochatConstant.getClientModuleId(), MmochatMain
									.getModuleInstID(),
							MmochatConstant.MSGCODE_MMOCHAT_C_20_20, (int) me
									.getRoleId()), wait);
			tlv.addItemEvent("50元" + pay.getType().toString(),
					new ClearDataTLV(), new AddDataTLV((int) 50),
					new AddDataTLV((int) pay.getId()), new SendDataTLV(
							MmochatConstant.getClientModuleId(), MmochatMain
									.getModuleInstID(),
							MmochatConstant.MSGCODE_MMOCHAT_C_20_20, (int) me
									.getRoleId()), wait);
			tlv.addItemEvent("100元" + pay.getType().toString(),
					new ClearDataTLV(), new AddDataTLV((int) 100),
					new AddDataTLV((int) pay.getId()), new SendDataTLV(
							MmochatConstant.getClientModuleId(), MmochatMain
									.getModuleInstID(),
							MmochatConstant.MSGCODE_MMOCHAT_C_20_20, (int) me
									.getRoleId()), wait);
			tlv.addItemEvent(MmochatUtil.wrapColor("面额选择错误，将导致充值失败，并且充值卡作废!",
					Color.yellow));

			tlv.addRightTLV(new CloseWinTLV(MmochatConstant.TLV_WIN_DELAYPAY));

			return MmochatUtil.tlvResponse(req.getHallState(), tlv);
		}
		case 4: {
			// 我的充值订单
			List<MmochatDelayPay> myOrders = new ArrayList<MmochatDelayPay>();
			for (MmochatDelayPay pay : delayPays.values()) {
				if (pay.getRoleId() == me.getRoleId()) {
					if (pay.getState() != MmochatDelayPayState.创建中) {
						myOrders.add(pay);
					}
				}
			}
			if (myOrders.size() == 0) {
				return MmochatUtil.msgbox(req.getHallState(), "您还没有进行过预充值!");
			}
			Collections.sort(myOrders);
			CreateTlvWin tlv = new CreateTlvWin();
			tlv.setWinType(WinType.List);
			tlv.setRightName("返回");
			tlv.setLeftName("详情");
			tlv.setTitle("我的预充值订单");
			tlv.setWinHeight(208);
			tlv.addRightTLV(new CloseWinTLV());
			int index = 1;
			for (MmochatDelayPay pay : myOrders) {
				String item = index + "、";
				index++;
				if (pay.getState() == MmochatDelayPayState.充值成功) {
					item += MmochatUtil.wrapColor("["
							+ pay.getState().toString() + "]" + pay.getMoney()
							+ "元" + pay.getType().toString(), Color.yellow);
				} else if (pay.getState() == MmochatDelayPayState.充值失败) {
					item += MmochatUtil.wrapColor("["
							+ pay.getState().toString() + "]" + pay.getMoney()
							+ "元" + pay.getType().toString(), Color.red);
				} else {
					item += "[" + pay.getState().toString() + "]"
							+ pay.getMoney() + "元" + pay.getType().toString();
				}
				tlv.addItemEvent(item, new ClearDataTLV(), new AddDataTLV(
						(int) pay.getId()));
			}
			tlv.addLeftTLV(new SendDataTLV(MmochatConstant.getClientModuleId(),
					MmochatMain.getModuleInstID(),
					MmochatConstant.MSGCODE_MMOCHAT_C_20_25, (int) me
							.getRoleId()));
			tlv.addLeftTLV(new ShowWaitingMsgBoxTLV());
			return MmochatUtil.tlvResponse(req.getHallState(), tlv);
		}
		default:
			break;
		}
		return null;
	}

	// 预充值功能，上传充值卡
	@SkymobiService
	public SkymobiProtocolMessage handleC_20_20(SkymobiHandler handler,
			Mmochat_20_20C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}

		MmochatDelayPay pay = delayPays.get(req.getPayId());
		if (pay == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙，请退出重试!");
		}
		int money = req.getMoney();
		if (money != 30 && money != 50 && money != 100) {
			delayPays.remove(pay.getId());
			return MmochatUtil
					.msgbox(req.getHallState(), "目前只支持30、50、100的充值卡!");
		}
		pay.setMoney(money);

		String msg = "请输入"
				+ MmochatUtil.wrapColor(money + "元" + pay.getType().toString(),
						Color.yellow) + "的卡号("
				+ pay.getType().getAccountLength() + "位数字)";

		ShowWaitingMsgBoxTLV wait = new ShowWaitingMsgBoxTLV();
		wait.setShowCancel(false);
		CreateEditBoxTLV edit = new CreateEditBoxTLV();
		edit.setTitle(msg);
		edit.setLeftName("上传");
		edit.setRightName("取消");
		edit.setContentLenMax(pay.getType().getAccountLength());
		edit.setBoxType(CreateEditBoxTLV.TYPE_MSGBOX);
		edit.setInputType(CreateEditBoxTLV.INPUT_NUM << 4);
		edit.addLeftTLV(new ClearDataTLV());
		edit.addLeftTLV(new AddDataTLV((int) me.getRoleId()));
		edit.addLeftTLV(new AddDataTLV((int) pay.getId()));
		edit.addLeftTLV(new AddEditBoxTLV());
		edit.addLeftTLV(new SendDataTLV(MmochatConstant.getClientModuleId(),
				MmochatMain.getModuleInstID(),
				MmochatConstant.MSGCODE_MMOCHAT_C_20_21, null));
		edit.addLeftTLV(wait);
		return MmochatUtil.tlvResponse(req.getHallState(), new CloseWinTLV(
				MmochatConstant.TLV_WIN_DELAYPAY), edit);
	}

	// 预充值功能，上传充值卡卡号
	@SkymobiService
	public SkymobiProtocolMessage handleC_20_21(SkymobiHandler handler,
			Mmochat_20_21C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}
		MmochatDelayPay pay = delayPays.get(req.getPayId());
		if (pay == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙，请退出重试!");
		}

		// 检查卡号
		MmochatPhoneCardType cardType = pay.getType();
		String account = req.getEdit();
		if (account.length() != cardType.getAccountLength()) {
			delayPays.remove(pay.getId());
			return MmochatUtil.msgbox(req.getHallState(), "卡号错误，卡号长度应该为"
					+ cardType.getAccountLength() + "位!请确认您提供的"
					+ MmochatUtil.wrapColor(cardType.toString(), Color.magenta)
					+ "!");
		}

		if (cardType == MmochatPhoneCardType.移动充值卡) {
			String sub = account.substring(0, 2);
			try {
				int num = Integer.parseInt(sub);
				if (num < 7 || num > 15) {
					delayPays.remove(pay.getId());
					return MmochatUtil.msgbox(req.getHallState(),
							"卡号输入有误，或您输入的是地方发行的移动充值卡!目前只支持全国通用的移动充值卡!");
				}
			} catch (NumberFormatException e) {
				delayPays.remove(pay.getId());
				return MmochatUtil.msgbox(req.getHallState(),
						"充值卡卡号输入有误，请重新输入!");
			}

			sub = account.substring(5, 7);
			try {
				int num = Integer.parseInt(sub);
				if (num < 1 || num > 31) {
					delayPays.remove(pay.getId());
					return MmochatUtil.msgbox(req.getHallState(),
							"卡号输入有误，或您输入的是地方发行的移动充值卡!目前只支持全国通用的移动充值卡!");
				}
			} catch (NumberFormatException e) {
				delayPays.remove(pay.getId());
				return MmochatUtil.msgbox(req.getHallState(),
						"充值卡卡号输入有误，请重新输入!");
			}
		}

		pay.setAccount(account);

		String msg = "请输入卡号为" + account + "的充值卡对应的密码("
				+ cardType.getPasswordLength() + "位)";

		ShowWaitingMsgBoxTLV wait = new ShowWaitingMsgBoxTLV();
		wait.setShowCancel(false);
		CreateEditBoxTLV edit = new CreateEditBoxTLV();
		edit.setTitle(msg);
		edit.setLeftName("上传");
		edit.setRightName("取消");
		edit.setContentLenMax(pay.getType().getPasswordLength());
		edit.setBoxType(CreateEditBoxTLV.TYPE_MSGBOX);
		edit.setInputType(CreateEditBoxTLV.INPUT_NUM << 4);
		edit.addLeftTLV(new ClearDataTLV());
		edit.addLeftTLV(new AddDataTLV((int) me.getRoleId()));
		edit.addLeftTLV(new AddDataTLV((int) pay.getId()));
		edit.addLeftTLV(new AddEditBoxTLV());
		edit.addLeftTLV(new SendDataTLV(MmochatConstant.getClientModuleId(),
				MmochatMain.getModuleInstID(),
				MmochatConstant.MSGCODE_MMOCHAT_C_20_22, null));
		edit.addLeftTLV(wait);
		return MmochatUtil.tlvResponse(req.getHallState(), edit);
	}

	// 预充值功能，上传充值卡密码
	@SkymobiService
	public SkymobiProtocolMessage handleC_20_22(SkymobiHandler handler,
			Mmochat_20_22C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}
		MmochatDelayPay pay = delayPays.get(req.getPayId());
		if (pay == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙，请退出重试!");
		}

		// 检查密码
		MmochatPhoneCardType cardType = pay.getType();
		String password = req.getEdit();
		if (password.length() != cardType.getPasswordLength()) {
			delayPays.remove(pay.getId());
			return MmochatUtil.msgbox(req.getHallState(), "密码错误，密码长度应该为"
					+ cardType.getPasswordLength() + "位!请确认您提供的是"
					+ MmochatUtil.wrapColor(cardType.toString(), Color.magenta)
					+ "!");
		}

		pay.setPassword(password);

		String msg = "请再次输入密码!";

		ShowWaitingMsgBoxTLV wait = new ShowWaitingMsgBoxTLV();
		wait.setShowCancel(false);
		CreateEditBoxTLV edit = new CreateEditBoxTLV();
		edit.setTitle(msg);
		edit.setLeftName("上传");
		edit.setRightName("取消");
		edit.setContentLenMax(pay.getType().getPasswordLength());
		edit.setBoxType(CreateEditBoxTLV.TYPE_MSGBOX);
		edit.setInputType(CreateEditBoxTLV.INPUT_NUM << 4);
		edit.addLeftTLV(new ClearDataTLV());
		edit.addLeftTLV(new AddDataTLV((int) me.getRoleId()));
		edit.addLeftTLV(new AddDataTLV((int) pay.getId()));
		edit.addLeftTLV(new AddEditBoxTLV());
		edit.addLeftTLV(new SendDataTLV(MmochatConstant.getClientModuleId(),
				MmochatMain.getModuleInstID(),
				MmochatConstant.MSGCODE_MMOCHAT_C_20_23, null));
		edit.addLeftTLV(wait);
		return MmochatUtil.tlvResponse(req.getHallState(), edit);
	}

	// 预充值功能，再次上传充值卡密码
	@SkymobiService
	public SkymobiProtocolMessage handleC_20_23(SkymobiHandler handler,
			Mmochat_20_23C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}
		MmochatDelayPay pay = delayPays.get(req.getPayId());
		if (pay == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙，请退出重试!");
		}

		// 检查密码
		MmochatPhoneCardType cardType = pay.getType();
		String password = req.getEdit();
		if (password.length() != cardType.getPasswordLength()) {
			delayPays.remove(pay.getId());
			return MmochatUtil.msgbox(req.getHallState(), "密码错误，密码长度应该为"
					+ cardType.getPasswordLength() + "位!请确认您提供的是"
					+ MmochatUtil.wrapColor(cardType.toString(), Color.magenta)
					+ "!");
		}
		if (pay.getPassword() == null || !pay.getPassword().equals(password)) {
			delayPays.remove(pay.getId());
			return MmochatUtil.msgbox(req.getHallState(),
					"您2次上传的密码不一致，请重新提交充值卡信息!");
		}
		pay.setState(MmochatDelayPayState.等待受理);

		return MmochatUtil.msgbox(req.getHallState(), MmochatUtil.wrapColor(
				"预充值订单创建成功!元宝不会马上到账，一般1至12小时内到账!\n", Color.yellow)
				+ "元宝到账后您会收到系统消息提醒!您可以在我的订单中查看订单状态。");
	}

	// 处理预充值订单
	public static String dealDelayPayOrder(int gmId, int orderId,
			boolean success, String hint, Integer trueMoney) {
		MmochatDelayPay pay = delayPays.get(orderId);
		if (pay == null) {
			return "订单不存在!订单ID:" + orderId;
		}
		if (pay.getState() != MmochatDelayPayState.等待受理) {
			return "处理失败，此订单已被受理过!当前状态为:" + pay.getState().toString();
		}
		synchronized (pay) {
			if (pay.getState() != MmochatDelayPayState.等待受理) {
				return "处理失败，此订单已被受理过!当前状态为:" + pay.getState().toString();
			}
			String retMsg = "";
			if (!success) {
				// 失败
				if (hint != null) {
					pay.setHint(hint);
				} else {
					pay.setHint("充值卡的卡号或密码不正确，可能是您输入错误!");
				}
				pay.setState(MmochatDelayPayState.充值失败);
				pay.setDealGmId(gmId);
				retMsg = "处理完毕，此充值卡充值失败!";
				String msg = "您参加"
						+ MmochatUtil.wrapColor("预充值活动", Color.yellow) + "，"
						+ MmochatUtil.wrapColor("提交的充值卡信息有误，充值失败", Color.red)
						+ "!";
				sendKufuPrivateMsg(pay.getRoleId(), msg, false);
			} else {
				// 成功
				MmochatPlayer me = null;
				try {
					me = MmochatGmService.getRoleInfoById(pay.getRoleId());
				} catch (Exception e) {
					return "读取用户数据失败，请重试!当前尚未给用户发放元宝。";
				}

				int money = pay.getMoney();
				if (trueMoney != null) {
					money = trueMoney;
				}
				pay.setTrueMoney(money);
				if (money > 0) {
					int trueExchangeRate = MmochatUtil.getRandomValue(
							MmochatConstant.delayPayMinExchangeRate,
							MmochatConstant.delayPayMaxExchangeRate);
					int bigMoney = money * trueExchangeRate;// 元宝数
					int awardTimes = bigMoney
							/ MmochatConstant.payValuePerAward;// 抽奖次数

					try {
						MmochatDao.delayPayOrder(me.getRoleId(), bigMoney,
								awardTimes, me.getDao(), me.getExp());
					} catch (Exception e) {
						return "数据库繁忙，请稍候重试!当前尚未给用户发放元宝。";
					}
					curTotalDelayPay += money;
					delayPayTimes++;
					pay.setDealGmId(gmId);
					pay.setBigMoney(bigMoney);

					me.addBig_money(bigMoney);
					me.addRest_award_times(awardTimes);

					String msg = "您参加"
							+ MmochatUtil.wrapColor("预充值活动", Color.magenta)
							+ "，成功充值"
							+ MmochatUtil.wrapColor(money + "", Color.yellow)
							+ "元!您获得了"
							+ MmochatUtil
									.wrapColor(bigMoney + "", Color.yellow)
							+ "元宝("
							+ MmochatUtil.wrapColor("兑换比例1元="
									+ trueExchangeRate + "元宝", Color.green)
							+ ")，"
							+ MmochatUtil.wrapColor(awardTimes + "",
									Color.yellow) + "次充值抽奖机会，元宝和奖励已下发，请查收!";

					if (hint != null) {
						pay.setHint(hint);
					} else {
						pay.setHint(bigMoney + "元宝和" + awardTimes
								+ "次充值抽奖已下发\n兑换比例1:" + trueExchangeRate);
					}
					pay.setState(MmochatDelayPayState.充值成功);
					sendKufuPrivateMsg(pay.getRoleId(), msg, false);
					retMsg = "充值成功，成功充值" + money + "元，获得" + bigMoney
							+ "元宝(兑换比例1:" + trueExchangeRate + ")和"
							+ awardTimes + "次充值机会!";
				} else {
					retMsg = "充值成功，但充值金额为" + money + "元，未发放元宝!";
				}

			}
			return retMsg;
		}
	}

	// 按日期读取文件中的预充值数据
	public static List<MmochatDelayPay> getDelayPayDataFromFile(long startTick,
			long endTick) {
		return getDelayPayDataFromFile(null, startTick, endTick);
	}

	public static List<MmochatDelayPay> getDelayPayDataFromFile(Integer roleId,
			long startTick, long endTick) {
		File root = new File("pay");
		File[] files = root.listFiles();
		List<MmochatDelayPay> pays = new ArrayList<MmochatDelayPay>();
		if (files != null) {
			Gson gson = new Gson();
			for (File file : files) {
				if (!file.isFile()) {
					continue;
				}

				String str = MmochatUtil.readFile(file);
				if (str != null) {
					Map<Integer, MmochatDelayPay> data = gson.fromJson(str,
							new TypeToken<Map<Integer, MmochatDelayPay>>() {
							}.getType());
					if (data != null) {
						for (MmochatDelayPay pay : data.values()) {
							if (pay.getCreateTime() >= startTick
									&& pay.getCreateTime() < endTick) {
								if (roleId == null || roleId == pay.getRoleId()) {
									pays.add(pay);
								}
							}
						}
					}
				}
			}
		}
		return pays;
	}

	// 读取指定时间内的所有预充值数据
	public static List<MmochatDelayPay> getDelayPayData(String startDate,
			String endDate) {
		Date start = null, end = null;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		try {
			start = sdf.parse(startDate);
			end = sdf.parse(endDate);
		} catch (ParseException e) {
			return null;
		}
		long startTick = start.getTime();
		long endTick = end.getTime();
		List<MmochatDelayPay> data = getDelayPayDataFromFile(startTick, endTick);

		for (MmochatDelayPay pay : delayPays.values()) {
			if (pay.getCreateTime() >= startTick
					&& pay.getCreateTime() < endTick) {
				data.add(pay);
			}
		}
		return data;
	}

	// 读取指定时间内特定GM处理的所有预充值数据
	public static List<MmochatDelayPay> getDelayPayDataByGmId(int gmId,
			String startDate, String endDate) {
		List<MmochatDelayPay> all = getDelayPayData(startDate, endDate);
		List<MmochatDelayPay> data = new ArrayList<MmochatDelayPay>();
		for (MmochatDelayPay pay : all) {
			if (pay.getDealGmId() != null && pay.getDealGmId() == gmId) {
				data.add(pay);
			}
		}
		return data;
	}

	// 读取指定时间内GM处理的所有预充值数据:Map<GMID,MmochatDelayPay>
	public static Map<Integer, List<MmochatDelayPay>> getDelayPayDataByGmId(
			String startDate, String endDate) {
		List<MmochatDelayPay> all = getDelayPayData(startDate, endDate);
		Map<Integer, List<MmochatDelayPay>> data = new ConcurrentHashMap<Integer, List<MmochatDelayPay>>();
		for (MmochatDelayPay pay : all) {
			if (pay.getDealGmId() != null) {
				List<MmochatDelayPay> list = data.get(pay.getDealGmId());
				if (list == null) {
					list = new ArrayList<MmochatDelayPay>();
				}
				list.add(pay);
				data.put(pay.getDealGmId(), list);
			}
		}
		return data;
	}

	// 查询特定玩家的预充值订单
	public static List<MmochatDelayPay> getDelayPayDataByRole(int roleId,
			String startDate, String endDate) {
		Date start = null, end = null;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		try {
			start = sdf.parse(startDate);
			end = sdf.parse(endDate);
		} catch (ParseException e) {
			return null;
		}
		long startTick = start.getTime();
		long endTick = end.getTime();
		List<MmochatDelayPay> data = getDelayPayDataFromFile(roleId, startTick,
				endTick);

		for (MmochatDelayPay pay : delayPays.values()) {
			if (pay.getCreateTime() >= startTick
					&& pay.getCreateTime() < endTick
					&& pay.getRoleId() == roleId) {
				data.add(pay);
			}
		}
		return data;
	}

	// 加载所有等待受理的历史预充值订单
	public static void loadUnDealedDelayPay() {
		try {
			List<MmochatDelayPay> pays = new ArrayList<MmochatDelayPay>();
			try {
				File root = new File("pay");
				File[] files = root.listFiles();
				if (files != null) {
					Gson gson = new Gson();
					for (File file : files) {
						if (!file.isFile()) {
							continue;
						}

						String str = MmochatUtil.readFile(file);
						if (str != null) {
							boolean needUpdate = false;
							Map<Integer, MmochatDelayPay> data = gson
									.fromJson(
											str,
											new TypeToken<Map<Integer, MmochatDelayPay>>() {
											}.getType());
							if (data != null) {
								for (MmochatDelayPay pay : data.values()) {
									if (pay.getState() == MmochatDelayPayState.等待受理) {
										pays.add(pay);
										pay.setState(MmochatDelayPayState.关闭);
										needUpdate = true;
									}
								}
							}
							if (needUpdate) {
								String delayPayData = gson
										.toJson(
												data,
												new TypeToken<Map<Integer, MmochatDelayPay>>() {
												}.getType());
								if (delayPayData != null
										&& delayPayData.length() > 0) {
									try {
										FileWriter writer = new FileWriter(file);
										writer.write(delayPayData);
										writer.close();
									} catch (Exception e) {
										e.printStackTrace();
									}
								}
							}
						}
					}
				}
			} catch (JsonParseException e) {
				e.printStackTrace();
			}
			if (pays.size() > 0) {
				for (MmochatDelayPay pay : pays) {
					pay.resetId();
					pay.setState(MmochatDelayPayState.等待受理);
					delayPays.put(pay.getId(), pay);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 我的充值订单详情
	@SkymobiService
	public SkymobiProtocolMessage handleC_20_25(SkymobiHandler handler,
			Mmochat_20_25C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}

		MmochatDelayPay pay = delayPays.get(req.getPayId());
		if (pay == null) {
			return MmochatUtil.msgbox(req.getHallState(), "此订单已不存在!");
		}
		CreateTlvWin tlv = new CreateTlvWin();
		tlv.setWinType(WinType.Text);
		tlv.setRightName("返回");
		tlv.setTitle("订单详情");
		tlv.setWinHeight(208);
		tlv.addRightTLV(new CloseWinTLV());
		String content = "";
		content += MmochatUtil.wrapColor("类型:", Color.green);
		content += pay.getType().toString() + "\n";
		content += MmochatUtil.wrapColor("面额:", Color.green);
		content += pay.getMoney() + "元\n";
		content += MmochatUtil.wrapColor("卡号:", Color.green);
		content += pay.getAccount() + "\n";
		content += MmochatUtil.wrapColor("状态:", Color.green);
		content += pay.getState().toString() + "\n";
		content += MmochatUtil.wrapColor("处理结果:", Color.green);
		content += pay.getHint();

		tlv.setContent(new Text(content));
		return MmochatUtil.tlvResponse(req.getHallState(), tlv);
	}
}
